我有这些表格:
CREATE TABLE [dbo].[Books] (
[id] int IDENTITY(1, 1) NOT NULL
, [Title] varchar(1000) NOT NULL
, [Publisher] varchar(1000) NULL
, [ISBN] varchar(50) NULL
, [Pages] int NULL
, [Date] date NULL
, [Plot_Summary] varchar(MAX) NULL)
ON [PRIMARY]
CREATE TABLE [dbo].[Characters] (
[id] int IDENTITY(1, 1) NOT NULL
, [Name] varchar(1000) NOT NULL)
ON [PRIMARY]
CREATE TABLE [dbo].[Book_Char] (
[id] int IDENTITY(1, 1) NOT NULL
, [Book_id] int NOT NULL
, [Char_id] int NOT NULL)
ON [PRIMARY]
当我使用此查询时:
SELECT b.title AS Title
, c.[Name] AS Char_Name
, b.Plot_Summary AS Summary
FROM Books b
INNER JOIN Book_Char bc ON b.id = bc.Book_id
INNER JOIN Characters c ON c.id = bc.Char_id
很自然地,我得到了这个结果:
Title Char_Name Summary
---------------------------
title1 Name1 Summary1
title1 Name2 Summary1
title1 Name3 Summary1
title2 Name1a Summary2
title2 Name2a Summary2
title2 Name3a Summary2
我想要的是:
Title Char_Name Summary
---------------------------
title1 Name1 Summary1
Name2
Name3
title2 Name1a Summary2
Name2a
Name3a
我在工会的尝试:
SELECT '' AS Title
, c.[Name] AS Char_Name
, '' AS Summary
FROM Books b
INNER JOIN Book_Char bc ON b.id = bc.Book_id
INNER JOIN Characters c ON c.id = bc.Char_id
UNION
SELECT b.title
, ''
, b.Plot_Summary
FROM Books b
INNER JOIN Book_Char bc ON b.id = bc.Book_id
INNER JOIN Characters c ON c.id = bc.Char_id
给出:
Title Char_Name Summary
---------------------------
Name1
Name1a
Name2
Name2a
Name3
Name3a
title1 Summary1
title2 Summary2
我是工会的新手,我甚至不知道这是否正确答案。我需要理解这一点;我不只是在寻找codez。我怎么能这样做,它是如何工作的?
答案 0 :(得分:3)
您可以在数据库中执行所需操作。但是,这种表示考虑因素通常在应用程序层更好。这是一种方法:
with bc as (
SELECT b.title AS Title, c.[Name] AS Char_Name, b.Plot_Summary AS Summary
FROM Books b INNER JOIN
Book_Char bc
ON b.id = bc.Book_id INNER JOIN
Characters c
ON c.id = bc.Char_id
)
select (case when seqnum = 1 then bc.title else '' end) as title, bc.Char_name,
(case when seqnum = 1 then bc.Summary else '' end) as Summary
from (select bc.*, row_number() over (partition by title order by char_name) as seqnum
from bc
) bc
order by bc.title, bc.char_name;
但是,查询的真正问题在于,您希望按特定顺序获得结果。您只能在使用order by
时按特定顺序(保证)获得结果。而且,您的查询没有order by
。
答案 1 :(得分:1)
如果您使用SQL Server 2012或更高版本,则另一个选项是使用LAG()函数来查看" peek"在最后一个值。我还建议对ID而不是值进行排序,因为您可能有书籍或具有重复值的字符。 Fiddle available here.
SELECT
[Title] = B.Title
, [Name] = C.Name
, [Summary] = B.Plot_Summary
, [dTitle] = CASE WHEN LAG( BC.Book_id, 1 ) OVER ( ORDER BY BC.Book_id, BC.Char_id ) = BC.Book_id
THEN ''
ELSE B.Title
END
, [dName] = CASE WHEN LAG( BC.Char_id, 1 ) OVER ( ORDER BY BC.Book_id, BC.Char_id ) = BC.Char_id
THEN ''
ELSE C.Name
END
, [dSummary] = CASE WHEN LAG( BC.Book_id, 1 ) OVER ( ORDER BY BC.Book_id, BC.Char_id ) = BC.Book_id
THEN ''
ELSE B.Plot_Summary
END
FROM dbo.Books AS B
INNER JOIN dbo.Book_Char AS BC ON b.id = bc.Book_id
INNER JOIN dbo.Characters AS C ON c.id = bc.Char_id
ORDER BY BC.Book_id, BC.Char_id