SQL:内部联接+不存在

SQL:内部联接+不存在,sql,inner-join,not-exists,Sql,Inner Join,Not Exists,我正在尝试创建一个SQL语句,其中我需要连接3个表 招收学生 学生 科目 输出应该是 UserID 2 3 因为用户1已经注册了所有科目,而用户3和用户7仍然显示,因为一些科目仍然没有注册 我有以下SQL语句,但运气不好: SELECT Students.UserID FROM Students WHERE Students.YearID = 1 AND Students.UserID NOT IN (SELECT EnrollStudents.UserID

我正在尝试创建一个SQL语句,其中我需要连接3个表

招收学生

学生

科目

输出应该是

UserID
2
3
因为用户1已经注册了所有科目,而用户3和用户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 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
…等等。我认为您在示例输出和EnrollStudents表中混淆了StudentID和UserID


看起来,您正试图让所有第一年未注册所有第一年必修课程的学生获得资格,因此只希望获得学生2和3。您的数据包含了一个yearID组中的所有人,但我怀疑您实际拥有跨多个年份的数据,并且您明确关注的只是第一年的学生,以及与第一年要求相关的科目

第一个查询结果将预先汇总所讨论的一年的班级数量,这样就不必对每个学生重复这样做。就一次。。。作为一个未分配的连接,查询的其余部分将是笛卡尔式的,但每个人有一条记录,无论如何都没有重复的记录

接下来是其余的表/联接。获取注册科目仅与第一年相关的学生。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

如果一个学生没有注册至少一个科目,这将不起作用。如果注册学生为空,用户ID记录还会显示吗?@Madman是的,你说得对。我编辑了它,这应该可以做到。@eibhrum是的,正如您在sqlfiddle中看到的,用户7正在出现,但他们没有注册anything@eibhrum这不是我的观点。在Students表中有用户ID 1,3,7,但在EnrollStudents中引用的是用户ID 1,2,3。我想你指的是StudentID。很好地格式化了表格,sqlfiddle漂亮地导入了它们。
SELECT Students.UserID 
FROM Students 
WHERE Students.YearID = 1 
    AND Students.UserID NOT IN (SELECT EnrollStudents.UserID 
                                FROM EnrollStudents)
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
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)
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