我正在使用SQL Server。我发现自己在WHERE子句中使用以下语法进行复杂查询:
SELECT ..
WHERE StudentID IS NULL OR StudentID NOT IN (SELECT StudentID from Students)
想知道是否有更好的方法/更清洁的方式来替换它,因为这是我正在做的更大的查询的一个小例子,其中包括多个条件。
正如您所看到的,我正在尝试为特定列过滤其列值为null或无效id的行。
修改
课程:
|CourseID | StudentID | StudentID2|
|-----------------------------------|
| 1 | 100 | NULL |
| 2 | NULL | 200 |
| 3 | 1 | 1 |
学生
|StudentID | Name |
|--------------------
| 1 | A |
| 2 | B |
| 3 | C |
查询:
SELECT CourseID
FROM Courses
WHERE
StudentID IS NULL OR StudentID NOT IN (SELECT * FROM Students)
OR StudentID2 IS NULL OR StudentID2 NOT IN (SELECT * FROM Students)
结果:
| CourseID |
|-----------|
| 1 |
| 2 |
如您所见,课程1和2的学生无效。
答案 0 :(得分:2)
Alain很接近,除了studentID2列与课程表相关联。此外,这是将每个studentID列连接到students表的实例,并且最终WHERE正在测试学生ID的EITH是否失败,因此即使Student1有效且仍然在Student2上失败,它将捕获您想要的课程
SELECT
C.CourseID
FROM
Courses C
LEFT JOIN Students S
ON C.StudentId = S.StudentId
LEFT JOIN Students S2
OR C.StudentId2 = S2.StudentId
WHERE
S.StudentId IS NULL
OR S2.StudentID IS NULL
答案 1 :(得分:1)
这不是一个肯定的镜头,但我有经验,这是比一个问题更好的表演者:
SELECT CourseID from Courses WHERE
Courses.StudentID NOT exists (SELECT 1 FROM Students where Students.StudentID=nvl(Courses.StudentID,-1));
还在学生表中的StudentId上创建一个索引。
如果您的数据模型支持在2个表之间创建主键外键关系。这样你肯定会避免在课程表中的无效值。
更新后:
SELECT CourseID from Courses WHERE
Courses.StudentID NOT exists (SELECT 1 FROM Students where Students.StudentID=nvl(Courses.StudentID1,-1) or Students.StudentID=nvl(Courses.StudentID2,-1));
答案 2 :(得分:1)
NOT EXISTS模式很好,但是,你有几种方法可以做到这一点。
例如使用LEFT JOIN(两个左连接,因为检查了两个变量)
SELECT *
from Courses
LEFT JOIN Students Student1
on Courses.StudentId = Student1.StudentId
LEFT JOIN Students Student2
on Courses.StudentId2 = Student2.StudentId
WHERE
-- No matching Student
student1.StudentId IS NULL
and student2.StudentId IS NULL