优化WHERE子句SQL查询

时间:2013-11-30 11:46:29

标签: sql sql-server where

我正在使用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的学生无效。

3 个答案:

答案 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模式很好,但是,你有几种方法可以做到这一点。

您应该检查herehere

例如使用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