SQL 查询中“NOT IN”的危险
当尝试检查一个表中的数据是否在另一个表中不存在时,“NOT IN”运算符可能会导致意外结果,尤其是在处理空值时。
问题与“NOT IN”
在提供的查询中,“NOT IN”子句将子查询的结果与“Grade”表中的“ID_Courses”列进行比较:
Grade.ID_Courses NOT IN (SELECT ID_Courses FROM Evaluation WHERE NAME='JOHN' and Year=1)
如果子查询返回任何空值,“NOT IN”子句将计算为 false,即使指定的“JOHN”记录的“Year”为 1存在于“等级”表中。这是因为 SQL 中的三值逻辑将 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
通过使用这些替代方案,您可以确保查询准确识别指定数据不存在的记录存在于另一个表中,无论是否存在空值。
以上是为什么在 SQL 查询中使用 NOT EXISTS 或显式连接而不是 NOT IN?的详细内容。更多信息请关注PHP中文网其他相关文章!