SQL クエリにおける "NOT IN" の危険性
あるテーブルのデータが別のテーブルに存在しないかどうかを確認するクエリを試行する場合特に null を処理する場合、「NOT IN」演算子は予期しない結果を引き起こす可能性があります。
「NOT IN」の問題
提供されたクエリでは、「NOT IN」句がサブクエリの結果を列「ID_Courses」と比較します。 「グレード」テーブル内:
Grade.ID_Courses NOT IN (SELECT ID_Courses FROM Evaluation WHERE NAME='JOHN' and Year=1)
サブクエリが null 値を返した場合、「NOT」 IN" 句は、"年" 1 の指定された "JOHN" レコードが "グレード" テーブルに存在する場合でも、偽と評価されます。これは、SQL の 3 値ロジックが null を「不明」と解釈し、誤った評価につながるためです。
「NOT IN」の代替手段
この問題を回避するには場合は、NOT EXISTS や明示的な結合などの代替方法を使用することをお勧めします:
NOT EXISTS
SELECT Grade.ID_Courses, Course.ID_Courses, Grade.NAME, Course.NAME, Grade.ID_Courses, Evaluation.NAME, Evaluation.Year, Grade.Year from Grade LEFT JOIN Course ON Grade.ID_Courses=Course.ID_Courses LEFT JOIN Evaluation ON Grade.NAME=Evaluation.NAME AND GRADE.YEAR = Evaluation.YEAR WHERE Grade.NAME='JOHN' and Evaluation.NAME IS NULL GROUP BY Grade.ID_Courses
明示的結合
SELECT Grade.ID_Courses, Course.ID_Courses, Grade.NAME, Course.NAME, Grade.ID_Courses, Evaluation.NAME, Evaluation.Year, Grade.Year from Grade LEFT JOIN Course ON Grade.ID_Courses=Course.ID_Courses LEFT JOIN Evaluation ON Grade.NAME=Evaluation.NAME AND GRADE.YEAR = Evaluation.YEAR WHERE Grade.NAME='JOHN' and NOT (Evaluation.NAME IS NOT NULL) GROUP BY Grade.ID_Courses
これらの代替手段を使用すると、指定されたデータが存在しないレコードをクエリで正確に識別できるようになります。 null 値の存在に関係なく、他のテーブルに存在します。
以上がSQL クエリで NOT IN ではなく NOT EXISTS または明示的結合を使用するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。