【问题标题】:Remove duplicate data from query results从查询结果中删除重复数据
【发布时间】:2017-07-02 18:44:38
【问题描述】:

我有以下疑问:

 select 
    C.ClientID,
    C.FirstName + ' ' + C.LastName as ClientName,
    CAST(V.StartDate as date) as VisitDate,
    count(*) as 'Number of Visits'
 from
    Visit V
 Inner Join Client C on
    V.ClientID = C.ClientID
 group by 
    C.ClientID,
    C.FirstName + ' ' + C.LastName,
    CAST(V.StartDate as date)
 having
    count(*) > 3
 order by
    C.ClientID, 
    CAST(V.StartDate as date)

给出以下结果(名字是假的,以防有人想知道)

 ClientID   ClientName            VisitDate      Number of Visits
 75         Kay Taylor            2016-06-07     4
 372         Moses Mcgowan       2016-09-03      4
 422         Raven Mckay         2016-03-11      4
 422         Raven Mckay         2016-06-14      4
 679         Ulysses Booker      2016-01-09      4
 696         Timon Turner        2016-07-06      4
 1063        Quyn Wall           2016-06-25      4
 1142        Garth Moran         2016-11-20      4
 1142        Garth Moran         2016-11-21      4
 1563        Hedley Gutierrez    2016-01-07      4
 1563        Hedley Gutierrez    2016-01-17      4
 1563        Hedley Gutierrez    2016-01-21      4
 1563        Hedley Gutierrez    2016-01-27      4
 1563        Hedley Gutierrez    2016-01-28      4
 1563        Hedley Gutierrez    2016-01-30      4
 1563        Hedley Gutierrez    2016-02-27      4
 1563        Hedley Gutierrez    2016-03-26      4
 1563        Hedley Gutierrez    2016-04-06      4
 1563        Hedley Gutierrez    2016-04-09      4
 1563        Hedley Gutierrez    2016-04-22      4
 1563        Hedley Gutierrez    2016-05-06      4
 1563        Hedley Gutierrez    2016-05-26      4
 1563        Hedley Gutierrez    2016-06-02      4
 1563        Hedley Gutierrez    2016-07-14      4
 1563        Hedley Gutierrez    2016-07-29      4
 1563        Hedley Gutierrez    2016-08-09      7
 1563        Hedley Gutierrez    2016-09-01      4
 1563        Hedley Gutierrez    2016-09-23      4
 1563        Hedley Gutierrez    2016-12-07      4
 1636        Kiara Lowery        2016-01-12      4
 2917        Cynthia Carr        2016-06-21      4
 2917        Cynthia Carr        2016-10-21      4
 3219        Alan Monroe         2016-01-02      4
 3219        Alan Monroe         016-02-27       4
 3219        Alan Monroe         2016-09-01      5
 4288        Natalie Mitchell    2016-03-19      4

我怎样才能让结果只显示一次 ClientID 和 ClientName 所以结果是这样的?

 ClientID   ClientName            VisitDate      Number of Visits
 75         Kay Taylor            2016-06-07     4
 372         Moses Mcgowan       2016-09-03      4
 422         Raven Mckay         2016-03-11      4
                                 2016-06-14      4
 679         Ulysses Booker      2016-01-09      4
 696         Timon Turner        2016-07-06      4
 1063        Quyn Wall           2016-06-25      4
 1142        Garth Moran         2016-11-20      4
                                 2016-11-21      4
 1563        Hedley Gutierrez    2016-01-07      4
                                 2016-01-17      4
                                 2016-01-21      4
                                 2016-01-27      4
                                 2016-01-28      4
                                 2016-01-30      4
                                 2016-02-27      4
                                 2016-03-26      4
                                 2016-04-06      4
                                 2016-04-09      4
                                 2016-04-22      4
                                 2016-05-06      4
                                 2016-05-26      4
                                 2016-06-02      4
                                 2016-07-14      4
                                 2016-07-29      4
                                 2016-08-09      7
                                 2016-09-01      4
                                 2016-09-23      4
                                 2016-12-07      4
 1636        Kiara Lowery        2016-01-12      4
 2917        Cynthia Carr        2016-06-21      4
                                 2016-10-21      4
 3219        Alan Monroe         2016-01-02      4
 3219                            016-02-27       4
                                 2016-09-01      5
 4288        Natalie Mitchell    2016-03-19      4

【问题讨论】:

  • 你不应该为此使用 sql
  • 在您的应用程序代码中执行此操作。
  • 我同意 HB,这在表示层处理得更好。报告工具将使用正确的设置自动执行此操作。
  • 这将是理想的,但不幸的是,这是一个需要直接进入 Excel 电子表格的数据集,因此这里没有报告层,结果可能有数千个,因此无法手动完成.
  • @James 你可以在 excel 中使用数据透视表。

标签: sql-server tsql


【解决方案1】:

实际上,您想要的不是删除重复项,而是不显示它们。

为此,您可以使用带有ROW_NUMBER()CASE 语句并在第一行显示值,并在ELSE 分支(其他行)上显示NULL''

select 
   CASE
       WHEN ROW_NUMBER() OVER (PARTITION BY C.ClientID ORDER BY CAST(V.StartDate as date) ASC) = 1 
           THEN C.ClientID
       ELSE NULL
   END as ClientID,
   CASE 
       WHEN ROW_NUMBER() OVER (PARTITION BY C.ClientID ORDER BY CAST(V.StartDate as date) ASC) = 1 
           THEN C.FirstName + ' ' + C.LastName
       ELSE NULL 
   END as ClientName,
   CAST(V.StartDate as date) as VisitDate,
   count(*) as 'Number of Visits'
from
   Visit V
Inner Join Client C on
   V.ClientID = C.ClientID
group by 
   C.ClientID,
   C.FirstName + ' ' + C.LastName,
   CAST(V.StartDate as date)
having
   count(*) > 3
order by
   C.ClientID, 
   CAST(V.StartDate as date)

【讨论】:

    【解决方案2】:

    试试这个:

    DECLARE @Table TABLE (ClientId NVARCHAR(5), ClientName NVARCHAR(6), VisitDate DATE, NumOfVisits INT)
    
    INSERT INTO @Table VALUES ('75' , 'A_NAME' , '2016-06-07' , '4' ),('372' , 'B_NAME' , '2016-09-03' , '4' ),
      ('422' , 'C_NAME' , '2016-03-11' , '4' ),('500' , 'D_NAME' , '2016-03-15' , '4'),
      ('500' , 'D_NAME' , '2016-03-19' , '4' ),('500' , 'D_NAME' , '2016-03-20' , '4'),
      ('500' , 'D_NAME' , '2016-07-15' , '4' ),('500' , 'D_NAME' , '2016-09-13' , '4'),
      ('600' , 'E_NAME' , '2016-03-19' , '4' ),('600' , 'E_NAME' , '2016-03-20' , '4'),
      ('600' , 'E_NAME' , '2016-07-15' , '4' ),('600' , 'E_NAME' , '2016-09-13' , '4')
    
    ;WITH A AS (
    SELECT ROW_NUMBER() OVER(PARTITION BY ClientID ORDER BY ClientID) row_id,* FROM (
    
                         -----------------------------------------
    SELECT * FROM @Table --- replace this line with your query----
                         -----------------------------------------
    
    
    ) Main_Result ) SELECT ISNULL(BB.ClientID,'')ClientID,ISNULL(BB.ClientName,'')ClientName,AA.VisitDate,AA.NumOfVisits
    FROM A AA LEFT JOIN (SELECT * FROM A BB WHERE BB.row_id=1) BB ON AA.ClientID = BB.ClientID AND AA.row_id =BB.row_id
                 ORDER BY CONVERT(INT,AA.ClientID)
    

    希望这会有所帮助。 :)

    您可以直接执行此操作以从示例数据中获取示例结果。 :)

    【讨论】:

      【解决方案3】:

      您可以使用 GROUP BY 解决此问题,按 (ClientID, VisitDate) 分组。

      在此处查看响应 1097:Using group by on multiple columns

      注意:在您的 ORDER BY 中不必使用 CAST(V.StartDate as date),您可以使用 VisitDate,因为它存在于您的 SELECT 中:... CAST(V.StartDate as date) as VisitDate,

      编辑: 试试这个:

      SELECT  
          C.ClientID,
          C.FirstName + ' ' + C.LastName as ClientName,
          CAST(V.StartDate as date) as VisitDate,
          count(*) as 'Number of Visits'
       from
          Visit V
       Inner Join Client C on
          V.ClientID = C.ClientID
       group by 
          (C.ClientID, VisitDate)
       having
          count(*) > 3
       order by
          C.ClientID, 
          VisitDate
      

      【讨论】:

      • 这有什么帮助?对 varchar 列进行排序确实会导致奇怪的排序,这取决于日期的格式。如果要按日期排序,转换为日期会有所不同。
      • 这根本不是问的问题,问题是只显示一条记录的名称和id,其他同名/id的行留空
      • 好的。然后我认为您需要对 VisitDate 和 Number of Visits 列使用字符串连接。之后,您可以将每个值拆分为不同的行。见:[链接]codeproject.com/articles/691102/…-stackoverflow.com/questions/17591490/…
      【解决方案4】:

      我希望下面的查询能做到这一点.... :)

      WITH CTE AS 
      (
       select top 100 percent
          cast(C.ClientID as nvarchar(255)) as ClientID,
          C.FirstName + ' ' + C.LastName as ClientName,
          CAST(V.StartDate as date) as VisitDate,
          count(*) as 'Number of Visits',
          row_number() over (partition by C.ClientID,C.FirstName + ' ' + C.LastName  ORDER BY CAST(V.StartDate as date) ) as rw_num
       from
          Visit V
       Inner Join Client C on
          V.ClientID = C.ClientID
       group by 
          C.ClientID,
          C.FirstName + ' ' + C.LastName,
          CAST(V.StartDate as date)
       having
          count(*) > 3
       order by
          min(C.ClientID), 
          min(CAST(V.StartDate as date))
      
      )
      
      select case 
             when rw_num<>1 then '' else  ClientID end as ClientID,
             case
             when rw_num<>1 then '' else  ClientName end as ClientName,
             VisitDate, [Number of Visits]
      from CTE
      

      结果:

      我的测试表中的测试数据:

      【讨论】:

        【解决方案5】:

        我会将您的初始查询用作 CTE 或子查询来替换 #TMP_DATA。下面是我将如何做到这一点。使用带有 LEAD 函数的 CASE 来确定是否应显示 ClientID 和 ClientName 中的数据:

        SELECT
        CASE WHEN CAST(LAG(T.ClientID,1,'') OVER (PARTITION BY T.ClientID ORDER BY T.ClientID,T.VisitDate) AS VARCHAR) = T.ClientID THEN '' ELSE CAST(T.ClientID AS VARCHAR) END AS ClientID,
        CASE WHEN LAG(T.ClientName,1,'') OVER (PARTITION BY T.ClientID ORDER BY      T.ClientID,T.VisitDate) = T.ClientName THEN '' ELSE T.ClientName END ClientName,
        T.VisitDate,
        T.[Number of Visits]
        FROM #TMP_DATA AS T
        

        结果集是: !https://i.stack.imgur.com/MBfEn.png

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-12-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-01-17
          • 1970-01-01
          • 2022-11-04
          相关资源
          最近更新 更多