唯一行中的重复数据,显示为空白

时间:2014-10-26 14:38:22

标签: sql sql-server

我有这些表格:

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

2 个答案:

答案 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