我正在尝试创建一个SQL语句,其中我需要连接3个表
招收学生
EnrollID UserID SubjID
1 1 1
2 1 2
3 1 3
4 3 1
5 7 2
学生
StudentID UserID YearID
1 1 1
2 3 1
3 7 1
受试者
SubjID SubjCode YearID
1 English 1
2 Math 1
3 Science 1
输出应该是…
UserID
2
3
由于User 1
已经登记了所有受试者,而User 3
和User 7
由于一些受试者仍然没有登记而仍然显示。
我有以下SQL语句,但运气不佳:
SELECT Students.UserID
FROM Students
WHERE Students.YearID = 1
AND Students.UserID NOT IN (SELECT EnrollStudents.UserID
FROM EnrollStudents)
有什么想法吗?
SELECT s.UserID
FROM Students AS s
LEFT OUTER JOIN EnrollStudents AS es ON s.UserID = es.UserID
GROUP BY s.UserID
HAVING COUNT(DISTINCT(es.SubjID)) < (SELECT COUNT(*) FROM Subjects)
等一下。我认为您在示例输出和EnrollStudents
表中混淆了"StudentID"one_answers"UserID"。
http://sqlfiddle.com/#!3/61618/1
select s.UserID
from Students s
left outer join (
select UserID
from EnrollStudents
group by UserID
having count(distinct SubjID) = 3
) a on s.UserID = a.UserID
where a.UserID is null
and s.YearID = 1
SQL Fiddle示例
看起来你正在努力让所有第一年没有报名参加第一年所需课程的学生获得资格,因此只希望获得学生2和3。你的数据中每个人都是一个一年级的ID,但我怀疑你的数据实际上跨越了多年,你只关心一年级的学生,以及那些与一年级要求相关的科目。
第一个查询(YrSubjects)结果将预先聚合所讨论的一年的班级数量,这样就不必为每个学生重复这样做。只有一次。。。有了它作为未分配的JOIN,查询的其余部分将是笛卡尔的,但每个人一条记录,无论如何都没有重复。
接下来是其余的表/联接。获取只与一年级相关科目的注册学生。where条款明确限制只招收那些"一年级"学生。
最后的HAVING条款适用于低于第一年要求的总科目的注册人数。有了这个查询,你就不会"固定"到你期望的某个硬编码数量的主题中。。。
SELECT
S.StudentID
FROM
( select count(*) as YrClasses
from
Subjects
where YearID = 1 ) YrSubjects,
Students S
JOIN EnrollStudents ES
on S.UserID = ES.UserID
JOIN Subjects S
ON ES.SubjID = S.SubjID
AND S.YearID = 1
WHERE
S.YearID = 1
HAVING
count(*) < YrSubjects.YrClasses