5

我正在尝试创建一个需要加入 3 个表的 SQL 语句

注册学生

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 3User 7仍然显示,因为一些科目仍未注册。

我有以下 SQL 语句没有运气:

SELECT Students.UserID 
FROM Students 
WHERE Students.YearID = 1 
    AND Students.UserID NOT IN (SELECT EnrollStudents.UserID 
                                FROM EnrollStudents)

有任何想法吗?

4

3 回答 3

6
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”和“UserID”。

http://sqlfiddle.com/#!3/61618/1

于 2012-07-12T15:34:29.570 回答
1

看起来您正在尝试让所有第一年没有参加所有第一年必修课程的学生获得资格,因此只希望获得学生 2 和 3。您的数据包含单个 yearID 组中的每个人,但我怀疑您实际上拥有跨越多年的数据,并且您明确关注的是第一年的那些学生,以及那些也与第一年要求相关的科目。

第一个查询 (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
于 2012-07-12T15:46:44.887 回答
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 小提琴示例

于 2012-07-12T15:30:08.263 回答