2014-10-26 132 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