关于sql server:从查询结果中删除重复数据

Remove duplicate data from query results

我有以下查询:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 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)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 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一次,结果是这样的?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 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


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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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)

试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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)

希望这可以帮助。 :)

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


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

1
2
3
4
5
6
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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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

结果:

enter image description here

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

enter image description here


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

请参阅此处的响应1097:在多列上使用group by

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

编辑:
试试这个:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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