2017-02-14 102 views
13

我有以下查询:从查询中删除重复的数据结果

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 
+0

您不应该为此使用sql – HoneyBadger

+0

在您的应用程序代码中执行此操作。 – GurV

+0

我同意HB,这在表现层处理得更好。报告工具会在正确的设置下自动执行此操作。 –

回答

11

其实,你想要的不是删除重复项,而是不显示它们。

为了做到这一点,你可以使用一个CASE语句ROW_NUMBER(),并显示在第1行的值并显示在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) 
0

你可以用GROUP BY解决这个问题,按(ClientID,VisitDate)分组。

看到响应1097这里:Using group by on multiple columns

注意:在你的ORDER BY是没有必要使用CAST(V.StartDate as date),因为它在你的SELECT存在,你可以使用VisitDate:... 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 
+0

这会如何帮助?在varchar列上排序确实会导致奇怪的排序,它取决于日期的格式。如果要按日期排序,则投射日期可能会有所不同。 – HoneyBadger

+0

这不是问什么问题,问题是只显示一个记录的名称和ID,并为相同名称/ ID的其他行保留为空 – HoneyBadger

+0

好的。然后,我认为你需要使用字符串连接的列VisitDate和访问次数。之后,您可以将每个值分成不同的行。参见:[link] https://www.codeproject.com/articles/691102/string-aggregation-in-the-world-of-sql-server [/ link] -http://stackoverflow.com/questions/17591490 /如何对做-A-查询与组-CONCAT功能于SQL服务器 –

3

试试这个:

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) 

希望这会有所帮助。 :)

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

0

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

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

0

我会使用您的初始查询作为CTE或作为子查询来替换#TMP_DATA。以下是我将如何做到这一点。使用CASE与引导功能,以确定是否应显示在客户端ID和客户端名的数据:

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