我在为以下场景编写SQL查询时遇到问题。我需要有人的帮助来编写查询。
我有以下表格7表:
1)标题
ID Title Author
-------------------------------------------------------------------------
1 The Hidden Language of Computer Hardware and Software Charles Petzold
2 Paths, Dangers, Strategies Nick Bostrom
3 The Smart Girl's Guide to Privacy Violet Blue
4 Introduction to Algorithms Thomas H. Cormen
5 Machine Learning in Action Peter Harrington
...
2)主题
ID Name
------------------------------------------
1 Science Fiction
2 Biography
3 Painting
...
3)主题
ID Name
-----------------------------------
1 Science
2 Technology
3 Music
4 Geography
...
4)成绩
ID Name
------------------------------------
1 Grade 1
2 Grade 2
3 Grade 3
4 Grade 4
5 Grade 5
...
5)TitleThemeAssociation
TitleID ThemeID
------------------------------------------
1 1
1 3
4 2
4 3
...
6)TitleSubjectAssociaton
TitleID SubjectID
---------------------------------
1 1
1 3
2 1
2 3
4 1
4 2
...
7)TitleGradeAssociaton
TitleID GradeID
1 1
1 2
1 3
2 1
2 2
...
我需要编写一个查询来仅显示缺少三个值(主题,主题和成绩)中的任何一个的标题,或者不完全分配值。如果分配了所有三个值(主题,主题,成绩),我不应该显示标题。在上面的数据集中,由于 TitleID 1 具有所有三个值,因此它不应出现在列表中。 TitleID 2 只分配了主题和成绩,但没有主题,所以它应该显示在输出中。如果标题有多个值列出标题,那么应该用逗号(,)分隔符联系它们。
因此上述数据集的最终输出应如下所示:
输出:
Title ID Title Theme Subject Grade
-------------------------------------------------------------------------------------------
2 Paths, Dangers, Strategies - Science, Music Grade 1, Grade 2
3 The Smart Girl's Guide to Privacy - - -
4 Introduction to Algorithms Biography, Painting Science, Technology -
5 Machine Learning in Action - - -
答案 0 :(得分:1)
你问的问题基本上有两个。第一个是如何在Theme
,Subject
或Grade
丢失时进行过滤。另一个是询问如何将这些项目连接成逗号分隔的列表。
以下查询应该是您要查找的内容:
Select Distinct
T.Id As [Title ID],
T.Title,
H.Theme,
S.Subject,
G.Grade
From Titles T
Outer Apply
(
Select Stuff(( Select ', ' + Name
From Themes H
Join TitleThemeAssociation TH On H.Id = TH.ThemeId
Where TH.TitleId = T.Id
For Xml Path('')), 1, 2, '') As Theme
From Themes
) H
Outer Apply
(
Select Stuff(( Select ', ' + Name
From Subjects S
Join TitleSubjectAssociaton TS On S.Id = TS.SubjectId
Where TS.TitleId = T.Id
For Xml Path('')), 1, 2, '') As Subject
From Subjects
) S
Outer Apply
(
Select Stuff(( Select ', ' + Name
From Grades G
Join TitleGradeAssociaton TG On G.Id = TG.GradeId
Where TG.TitleId = T.Id
For Xml Path('')), 1, 2, '') As Grade
From Grades
) G
Where H.Theme Is Null
Or S.Subject Is Null
Or G.Grade Is Null
答案 1 :(得分:1)
希望这有助于。
;WITH cte_Titles (ID,Title,Author) AS
(
SELECT 1,'The Hidden Language of Computer Hardware and Software','Charles Petzold' UNION ALL
SELECT 2,'Paths, Dangers, Strategies','Nick Bostrom' UNION ALL
SELECT 3,'The Smart Girls Guide to Privacy','Violet Blue' UNION ALL
SELECT 4,'Introduction to Algorithms','Thomas H. Cormen' UNION ALL
SELECT 5,'Machine Learning in Action','Peter Harrington'
),cte_Themes(ID,Name) AS
(
SELECT 1,'Science Fiction' UNION ALL
SELECT 2,'Biography' UNION ALL
SELECT 3,'Painting'
),cte_Subjects(ID,Name) AS
(
SELECT 1,'Science' UNION ALL
SELECT 2,'Technology' UNION ALL
SELECT 3,'Music' UNION ALL
SELECT 4,'Geography'
),cte_Grades(ID,Name) AS
(
SELECT 1,'Grade 1' UNION ALL
SELECT 2,'Grade 2' UNION ALL
SELECT 3,'Grade 3' UNION ALL
SELECT 4,'Grade 4' UNION ALL
SELECT 5,'Grade 5'
),cte_TitleThemeAssociation(TitleID,ThemeID) AS
(
SELECT 1,1 UNION ALL
SELECT 1,3 UNION ALL
SELECT 4,2 UNION ALL
SELECT 4,3
),cte_TitleSubjectAssociaton(TitleID,SubjectID) AS
(
SELECT 1, 1 UNION ALL
SELECT 1, 3 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 2, 3 UNION ALL
SELECT 4, 1 UNION ALL
SELECT 4, 2
),cte_TitleGradeAssociaton(TitleID,GradeID) AS
(
SELECT 1, 1 UNION ALL
SELECT 1, 2 UNION ALL
SELECT 1, 3 UNION ALL
SELECT 2, 1 UNION ALL
SELECT 2, 2
)
,cte_ResultSet AS
(
SELECT DISTINCT t.ID AS TitleID,
t.Title,
th.NAME AS Theme,
s.NAME AS Subject,
g.NAME AS Grade
FROM cte_Titles t
LEFT JOIN cte_TitleThemeAssociation tta
ON t.ID = tta.TitleID
LEFT JOIN cte_Themes th
ON tta.ThemeID = th.ID
LEFT JOIN cte_TitleSubjectAssociaton tsa
ON tsa.TitleID = t.ID
LEFT JOIN cte_Subjects s
ON tsa.SubjectID = s.ID
LEFT JOIN cte_TitleGradeAssociaton tga
ON tga.TitleID = t.ID
LEFT JOIN cte_Grades g
ON g.ID = tga.GradeID
)
SELECT DISTINCT Title
, STUFF((SELECT DISTINCT ',' + SUB.Theme AS [text()]
FROM cte_ResultSet SUB
WHERE SUB.TitleID = CAT.TitleID
FOR XML PATH('')
), 1, 1, '' ) AS Theme
, STUFF((SELECT DISTINCT ',' + SUB.Subject AS [text()]
FROM cte_ResultSet SUB
WHERE SUB.TitleID = CAT.TitleID
FOR XML PATH('')
), 1, 1, '' ) AS Subject
, STUFF((SELECT DISTINCT ',' + SUB.Grade AS [text()]
FROM cte_ResultSet SUB
WHERE SUB.TitleID = CAT.TitleID
FOR XML PATH('')
), 1, 1, '' ) AS Grade
FROM cte_ResultSet CAT