SQL查询需求:表记录对比与未完成指定课程员工查询
嘿,我来帮你搞定这两个SQL查询问题,都是日常做数据查询时经常碰到的场景,咱们一步步拆解:
问题1:查询表1中不存在于表2中的记录
这里有两种靠谱的写法,适配不同场景,还能避开常见坑:
方法1:用
NOT EXISTS子句(推荐)
这种写法在处理包含NULL值的场景时特别稳定,数据库优化器也更容易处理,性能通常不错:SELECT t1.* FROM 表1 t1 WHERE NOT EXISTS ( SELECT 1 FROM 表2 t2 WHERE t1.关联字段 = t2.关联字段 -- 替换成实际匹配字段,比如员工ID EmpID )划重点:一定要用两个表的唯一标识字段做关联(比如EmpID),别用可能重复的字段,不然结果会不准。
方法2:用
LEFT JOIN+IS NULL
这个写法逻辑特别直观,新手也能一眼看懂:SELECT t1.* FROM 表1 t1 LEFT JOIN 表2 t2 ON t1.关联字段 = t2.关联字段 WHERE t2.关联字段 IS NULL提示:如果表2的关联字段可能有NULL值,这个方法和
NOT IN的结果会不一样——NOT IN碰到子查询返回NULL时,会直接返回空表,这也是很多人踩坑的地方。
问题2:查询未完成特定课程(如急救)的员工
你说用NOT EXISTS和NOT IN时要么空表要么报错,大概率是关联条件没写对,或者没加上特定课程的过滤条件。咱们结合你已有的qryAllCompletedCourses来调整:
首先明确核心逻辑:要找出所有员工里,从来没完成过“急救”这门课的人。
正确的NOT EXISTS写法(强烈推荐)
这种写法不会因为NULL值出问题,逻辑也清晰:
SELECT e.EmpID, e.[LastName] & ", " & e.[FirstName] AS EmpName FROM tblEmployee e WHERE NOT EXISTS ( SELECT 1 FROM qryAllCompletedCourses q WHERE q.EmpID = e.EmpID AND q.CourseName = '急救' -- 替换成你的课程名称字段,比如CourseTitle )
要是不想用已有的查询,直接关联原始课程表(比如tblCompletedCourses和tblCourse)也可以:
SELECT e.EmpID, e.[LastName] & ", " & e.[FirstName] AS EmpName FROM tblEmployee e WHERE NOT EXISTS ( SELECT 1 FROM tblCompletedCourses cc JOIN tblCourse c ON cc.CourseID = c.CourseID WHERE cc.EmpID = e.EmpID AND c.CourseName = '急救' )
为什么你的NOT IN会出问题?
如果你的子查询返回的EmpID里有NULL值,NOT IN会直接返回空结果——因为SQL里NULL和任何值比较都是“未知”,整个条件就不成立。如果非要用NOT IN,必须先过滤掉NULL:
SELECT e.EmpID, e.[LastName] & ", " & e.[FirstName] AS EmpName FROM tblEmployee e WHERE e.EmpID NOT IN ( SELECT q.EmpID FROM qryAllCompletedCourses q WHERE q.CourseName = '急救' AND q.EmpID IS NOT NULL -- 这行必须加,不然可能返回空表 )
但还是更推荐NOT EXISTS,它的行为更稳定,性能也比NOT IN靠谱。
内容的提问来源于stack exchange,提问作者Scott
相关产品推荐
相关产品推荐

