0

2 つのテーブルを比較して、この操作の結果を処理しようとしています。

SELECT * FROM table1
WHERE table1.czlowiek_id NOT IN (
    SELECT table2.czlowiek_id
    FROM table2
    WHERE table1.czlowiek_id=table2.czlowiek_id
)  
OR table1.czlowiek_id IN (
    SELECT table2.czlowiek_id
    FROM table2
    WHERE table1.czlowiek_id=table2.czlowiek_id
    AND table2.szkolenie_id IN ('$selected_one')
    AND table1.instruktor IN ('$selected_two')
) 

別の WHERE ステートメントを追加して、このクエリの結果を処理するオプションはありますか?

4

3 に答える 3

4

で問題を解決できる場合がありますLEFT JOIN。これにより、table2 に存在しない table1 からすべての結果を取得し、さらに table2 にあり、要求されたフィルターに一致する table1 から結果を取得できます。

SELECT
    *
FROM
    table1
    LEFT JOIN table2 ON table1.czlowiek_id=table2.czlowiek_id
WHERE
    table2.czlowiek_id IS NULL
    OR (
        table2.szkolenie_id IN ('$selected_one')
        AND table1.instruktor IN ('$selected_two')
    )
于 2012-07-16T15:21:11.310 に答える
1

一連の括弧でステートメントをラップし、エイリアスを割り当てて (閉じた親に続いて)、それをテーブルのように使用できます。(これをインライン ビューと呼びます。)

SELECT q.*
  FROM (
         SELECT * FROM table1 ... /*your whole query here*/
       ) q
 WHERE ... 

WHERE 句で、インライン ビューによって返される任意の列を参照できます。(このアプローチは、小さい (適度なサイズの) 結果セットを返すインライン ビューでは比較的うまく機能します。しかし、より大きな結果セットでは、外側のクエリを実行する前に、そのビューを「実体化」するために多くの手間がかかります) . これは便利なパターンですが、このパターンを悪用して、インライン ビューを使用しない同等のステートメントよりもはるかにひどいパフォーマンスのステートメントを作成することもできます。

しかし、それがあなたの質問であるかどうかはわかりません。

WHERE 句に別の述語を追加できますか?

確かにできます...別のANDまたはORキーワードを追加して、条件付きテストを追加するだけです。AND と OR の優先順位に注意してください。予想される順序を指定するために括弧を使用することをお勧めします。違いがあります...

( a OR b ) AND c  
a OR ( b AND c)

しかし、あなたが尋ねている質問にも答えているかどうかはわかりません。

相関サブクエリでは、 EXISTSandNOT EXISTSではなくINandを使用できますNOT IN

これは同等の結果を返すと思います:

SELECT *
  FROM table1
 WHERE NOT EXISTS 
       ( SELECT 1 FROM table2
          WHERE table2.czlowiek_id=table1.czlowiek_id
       )
    OR EXISTS 
       ( SELECT 1 FROM table2
          WHERE table2.czlowiek_id=table1.czlowiek_id
            AND table2.szkolenie_id IN ('$selected_one')
            AND table1.instruktor IN ('$selected_two')
       )
于 2012-07-16T16:16:05.333 に答える
0

これを表現する別の方法があります。アイデアは、テーブル 2 からの情報を czlowiek_id レベルで集約し、szkolenie_id に関する情報が必要になる可能性があるため保持することです。

これにより、クエリがグループに変更され、その後に従来の結合とかなり通常の where 句が続きます。

select table1.*
from table1 left outer join
     (select czlowiek_id,
             (case when table2.szkolenie_id IN ('$selected_one') then 1
                   else 0
              end) as flag
      from table2
      group by czlowiek_id
     ) t2
     ON table1.czlowiek_id = t2.czlowiek_id
WHERE t2.czlowiek_id IS NULL OR
      (t2.flag = 1  AND table1.instruktor IN ('$selected_two') ) 
于 2012-07-16T16:00:39.450 に答える