SQL Server-给定一组列,查找集合中缺少的组合

SQL Server-给定一组列,查找集合中缺少的组合,sql,sql-server,set,Sql,Sql Server,Set,我有下表。我想得到的是缺少的学生、班级、书籍的组合。我下面有一个查询可以做到这一点,但我希望其他人提供更高效的查询,即可能使用group by查找缺少的组合的查询 在这里摆弄- 集合中的以下行是缺少的组合 Correct Result of My Query Below +---------+---------+-----------+ | Student | Class | Book | +---------+---------+-----------+ | Edwar

我有下表。我想得到的是缺少的学生、班级、书籍的组合。我下面有一个查询可以做到这一点,但我希望其他人提供更高效的查询,即可能使用group by查找缺少的组合的查询

在这里摆弄-

集合中的以下行是缺少的组合

 Correct Result of My Query Below
 +---------+---------+-----------+
 | Student |  Class  |   Book    |
 +---------+---------+-----------+
 | Edward  | English | NovelBook |
 | Frank   | English | NovelBook |
 +---------+---------+-----------+
我可以使用下面的查询来获得缺少的组合,但是我想要一个更快更有效的解决方案。基本上,我正在寻找其他更有效的技术,比如可能使用分组

WITH CTE_ClassBooks AS
(
   SELECT DISTINCT Class, Book FROM StudentBook
),
CTE_StudentClasses AS
(
   SELECT DISTINCT Student, Class FROM StudentBook
),
CTE_CombosOfStudentClassBooks AS
(
   SELECT DISTINCT b.Student, a.Class, a.Book 
   FROM CTE_ClassBooks a 
   INNER JOIN CTE_StudentClasses b ON a.Class = B.Class
)
SELECT * FROM CTE_CombosOfStudentClassBooks
EXCEPT
SELECT * FROM StudentBook

这可能会快一点,但您的路线似乎效率不高

;WITH cte AS (SELECT DISTINCT Class,Book FROM Table1)
SELECT b.Student,a.*
FROM cte a
JOIN Table1 b
    ON  a.Class = b.Class
LEFT JOIN Table1 c
    ON  a.Class = c.CLass
    AND a.Book = c.Book
    AND b.Student = c.Student
WHERE c.Class IS NULL

演示:

这使用了4次表扫描,很难喜欢使用旧式联接的答案,但如果没有CTE,它确实会得到要求的结果。谢谢,我感谢您的努力。但这只给出了这个数据集的正确答案。例如,如果我加上Charles、Math、CalcBook,它应该会告诉我Albert和Bridget失踪了。但事实并非如此。检查一下这里的SQL FIDLE只是缺少了一个独特的,但可以工作,而且速度快了15%。如果我用studentclassbooks和StudentBook表的CTE_组合的左连接替换我的EXCEPT,它将给出相同的查询计划。奇怪的是,SQL优化器在数据库中使用2个表扫描,而不是在后台执行其他操作,如哈希连接。
;WITH cte AS (SELECT DISTINCT Class,Book FROM Table1)
SELECT b.Student,a.*
FROM cte a
JOIN Table1 b
    ON  a.Class = b.Class
LEFT JOIN Table1 c
    ON  a.Class = c.CLass
    AND a.Book = c.Book
    AND b.Student = c.Student
WHERE c.Class IS NULL
SELECT S1.STUDENT,S1.CLASS,S2.BOOK FROM 
STUDENTBOOK S1,(SELECT DISTINCT CLASS,BOOK FROM STUDENTBOOK) S2
WHERE S1.CLASS = S2.CLASS
AND S1.BOOK <> S2.BOOK
EXCEPT
SELECT STUDENT,CLASS,BOOK FROM STUDENTBOOK