16

I have the following query:

 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) 

which gives the following results (names are fake in case anyone is wondering)

 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 

How can I get the results to show only the ClientID and ClientName once so the results are like this?

 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 
5
  • You shouldn't use sql for this Commented Feb 14, 2017 at 12:58
  • Do this in your application code. Commented Feb 14, 2017 at 12:59
  • I agree with HB, this is better handled at the presentation layer. Reporting tools will do this automatically with the right setting. Commented Feb 14, 2017 at 13:00
  • 1
    That would be ideal, but unfortunately this is a dataset that needs to go straight to an Excel spreadsheet so there's no reporting layer here and the results can be in the thousands so it can't be done manually. Commented Feb 14, 2017 at 13:04
  • 1
    @James you can use a pivot table in excel for that. Commented Feb 14, 2017 at 13:05

5 Answers 5

12
+50

Actually, what you want is not to remove duplicates, but not display them.

In order to do this you can use a CASE statement with ROW_NUMBER() and show the value on the 1st row and display either NULL or '' on the ELSE branch (the other rows):

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) 
Sign up to request clarification or add additional context in comments.

Comments

3

Try this:

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) 

Hope this helps. :)

you can execute this directly to get sample result from sample data. :)

Comments

0

You can solved this with GROUP BY, grouping by (ClientID, VisitDate).

See the response 1097 here: Using group by on multiple columns

Note: In your ORDER BY is not necessary to use CAST(V.StartDate as date) you can use VisitDate because it exists in your SELECT: ... CAST(V.StartDate as date) as VisitDate,

EDIT: Try this:

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 

3 Comments

How's that going to help? Sorting on a varchar column can indeed lead to odd sortings, it depends what format the date is in. If you want to sort by date, casting to a date can make a difference.
This is not what is asked at all, the question is to show the name and id just for one record, and leave it empty for the other rows with the same name/id
Ok. Then i think you need to use string concatenation for the columns VisitDate and Number of Visits. After, you can split each value in different rows. See: [link]codeproject.com/articles/691102/… -stackoverflow.com/questions/17591490/…
0

I hope the below query would do that.... :)

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 

Result:

enter image description here

My test Data in my test tables:

enter image description here

Comments

0

I would use your initial query as a CTE or as subquery to replace #TMP_DATA. Below is how I would do this. Using a CASE with the LEAD function to determine if the data in ClientID and ClientName should be displayed:

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 

The result set is: !https://i.sstatic.net/MBfEn.png

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.