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

时间:2014-02-01 04:27:50

标签: sql sql-server set

我有以下表格。我想得到的是学生,班级,书籍的缺失组合。 我在下面有一个查询 ,但我希望其他人提供更有效的查询(也就是那些使用group by的查询)来查找缺少的组合。

SQL FIDDLE HERE - http://sqlfiddle.com/#!6/16e2b/3

 StudentBook Table
 +---------+---------+--------------+
 | Student |  Class  |     Book     |
 +---------+---------+--------------+
 | Albert  | Math    | AlgebraBook  |
 | Albert  | Math    | FractionBook |
 | Bridget | Math    | AlgebraBook  |
 | Bridget | Math    | FractionBook |
 | Charles | Math    | AlgebraBook  |
 | Charles | Math    | FractionBook |
 | Debbie  | English | NovelBook    |
 | Debbie  | English | PoemBook     |
 | Edward  | English | PoemBook     |
 | Frank   | English | PoemBook     |
 +---------+---------+--------------+

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

 Correct Result of My Query Below
 +---------+---------+-----------+
 | Student |  Class  |   Book    |
 +---------+---------+-----------+
 | Edward  | English | NovelBook |
 | Frank   | English | NovelBook |
 +---------+---------+-----------+

我可以使用以下查询来获取Missing Combinations,但我想要一个更快更有效的解决方案。基本上我正在寻找 其他更有效的技术 ,例如可能使用Group By。

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

2 个答案:

答案 0 :(得分:1)

这可能会快一点,但你的路线似乎并不是非常低效。

;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

演示:SQL Fiddle

答案 1 :(得分:0)

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