我已经获得了一个大学毕业生的MySQL数据库和一个名为“受试者”的表格。包括:StudentID,SubjectName,Exams。
考试专栏是针对每门课程的考试。他们的名字有第一部分,第二部分,第一部分,第二部分等。学位课程的考试名称与其他课程不同,所以名称以'部分'开头。仅适用于学位,而A科可能适用于职业会计课程。
该表的简化版本如下所示:
StudentID Subject Exam
--------------------------------------
1234 Mathematics Part I
5678 Music Sect A
9101 Geography Part I
1234 Accountancy Sect A
请注意,有时人们会切换到学位课程,如上面的1234。我被要求写一个查询,找到所有没有参加任何学位相关考试的人。因此,他们不应该在结果中返回1234,因为他们已经完成了学位相关的考试(数学第一部分)以及非学位考试(会计学部分A)。
这个查询带我走了一些路,但是错过了像1234这样做过两种类型考试的人:
SELECT `StudentID` FROM `Subjects` WHERE `Exam` NOT IN ('Part I', 'Part II', etc)
我无法弄清楚如何优化查询。我试过这个,但它崩溃phpMyAdmin所以我猜它错了!
SELECT `StudentID` FROM `Subjects`
WHERE `Exam` NOT IN ('Part I', 'Part II')
AND `StudentID` NOT IN(SELECT `StudentID` FROM `Subjects` WHERE `Exam` LIKE 'Pt I%')
答案 0 :(得分:0)
这个查询带我走了一些路,但是错过了像1234这样做过两种类型考试的人:
SELECT
StudentID
FROMSubjects
WHEREExam
NOT IN(' Part I',' Part II'等)
正如您所注意到的,此查询将多次返回多个考试的学生。它只会过滤掉你不想要的那些主题。学生1234选择Sect A的元组将保留。
要解决这个问题,你需要考虑另一种方式:你想要的学生那些不是你不想要的学生
首先,你得到所有不想要的学生,一次:
SELECT DISTINCT `StudentID`
FROM `Subjects`
WHERE `Exam` IN ('Part I', 'Part II', etc)
现在,您要查询此列表中不的学生列表。您可以通过LEFT JOIN
所有科目列表(学生多次出席)和不需要的学生列表来完成此操作。只要完整列表中的名称可以与不需要的学生匹配,就会相应地填充不需要的。*列。如果无法完成此操作(即主题不属于不受欢迎的学生),则这些列将为NULL。
所以你只需选择那些unwanted.StudentId IS NULL
的元组。这些将填充第一个表格的列。其中您只需要StudentID。由于StudentID可能会多次出现,因此您也会在外部DISTINCT
上添加SELECT
子句。
SELECT DISTINCT wanted.StudentID FROM `Subjects` AS wanted
LEFT JOIN (
SELECT DISTINCT `StudentID`
FROM `Subjects`
WHERE `Exam` IN ('Part I', 'Part II', etc)
) AS unwanted
ON (wanted.StudentId = unwanted.StudentId)
WHERE unwanted.StudentId IS NULL;
Here你可以看到一个SQL小提琴;它按预期学生5678返回。