2014-10-26 83 views
1

我有这些表:重复数据,显示空白代替

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。我该怎么做,它是如何工作的?

回答

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

+0

哦,我的,那工作。正是我想要的。是的,我忘记了'ORDER BY'语句,我在蟾蜍的查询中已经有了它。我只是在复制时没有抓住它。我从来没有用过''。我用过分区,不敢相信我不记得那个。我猜,太关注'UNION'了。我必须去研究这个。 “seqnum”从哪里来?谢谢你! – pixelmeow 2014-10-26 14:56:17

+0

我是盲人。我看到seqnum。没关系那部分。 – pixelmeow 2014-10-26 15:02:26

1

如果您使用的是SQL Server 2012或更高版本,另一种选择是使用LAG()函数“偷看”最后一个值。我还建议使用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 
+0

我确实有出现在多本书中的角色。这个查询工作得很好,谢谢!我也接受你的答案。如果可以的话,我会将检查标记为两个答案! – pixelmeow 2014-10-28 15:20:52

+0

该查询在查询编辑器(Toad)中运行良好,但是当我尝试将其另存为视图时,它会引发错误:Value不能为空。参数名称:节点'我google了,但没有什么相关的。只是觉得你应该知道。 – pixelmeow 2014-10-28 15:38:12