我被问到这个技巧问题:
Table: Student
ID NAME
1 JOHN
2 MARY
3 ROBERT
4 DENNIS
Table: Grade
ID GRADE
1 A
1 A
1 F
2 B
3 A
如何编写SQL查询以返回所有从未获得成绩'F'或从未参加过课程的学生的DISTINCT名称(意思是,他们的成绩表中没有他们的ID)?
特技部分是,你不允许使用OUTER JOIN,UNION或DISTINCT。另外,为什么这是一个大问题?
预期结果是MARY,ROBERT,DENNIS(3行)。
答案 0 :(得分:3)
SELECT name FROM Student
WHERE
NOT EXISTS (SELECT * FROM Grade WHERE Grade.id = Student.id AND grade = 'F')
OR
NOT EXISTS (SELECT * FROM Grade WHERE Grade.id = Student.id);
您可以使用GROUP BY伪造一个不同的。
答案 1 :(得分:2)
如果你允许使用子查询,这样的东西可以工作。
SELECT `NAME`
FROM Student
WHERE 'F' NOT IN
(SELECT GRADE FROM Grade WHERE ID = Student.ID)
答案 2 :(得分:2)
SELECT name FROM student
WHERE (SELECT COUNT(*) FROM grade WHERE grade = 'F'
AND id = student.id) = 0
至少这是迄今为止最短的答案......
答案 3 :(得分:0)
您可以使用GROUP BY和聚合函数来伪造不同的。
答案 4 :(得分:0)
您希望排除所有参加过课程并获得“F”成绩的人。这样的事情可能有用:
SELECT NAME
FROM Student
WHERE 0 = (SELECT COUNT(*)
FROM Student
LEFT JOIN Grade
USING (ID)
WHERE GRADE='F')
GROUP BY NAME
答案 5 :(得分:0)
他们可能不希望您使用UNION,JOIN或DISTINCT的原因是,如果您尝试强制使用“优化”解决方案,其中一些查询可能会很慢。
我不太熟悉查询优化技术,但通常如果你使用其中的一些聚合器和JOIN,你可能会减慢查询速度,而不是让查询优化运行并根据你的表结构和内容组织你的SQL。 / p>
答案 6 :(得分:0)
SELECT name
FROM grade G, student S
WHERE (S.id = G.id AND 'F' NOT IN (SELECT G1.grade
FROM grade G1
WHERE G1.id = G.id))
OR
S.id NOT IN (SELECT id
FROM grade)
GROUP BY name