Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicate Counts - TSQL

I want to get All records that has duplicate values for SOME of the fields (i.e. Key columns).

My code:

CREATE TABLE #TEMP (ID int, Descp varchar(5), Extra varchar(6))
INSERT INTO #Temp
SELECT 1,'One','Extra1'
UNION ALL
SELECT 2,'Two','Extra2'
UNION ALL
SELECT 3,'Three','Extra3'
UNION ALL
SELECT 1,'One','Extra4'

SELECT ID, Descp, Extra FROM #TEMP
;WITH Temp_CTE AS
(SELECT *
 , ROW_NUMBER() OVER (PARTITION BY ID, Descp ORDER BY (SELECT 0)) 
    AS DuplicateRowNumber
    FROM #TEMP
)
SELECT * FROM Temp_cte 
DROP TABLE #TEMP

The last column tells me how many times each row has appeared based on ID and Descp values. I want that row but I ALSO need another column* that indicates both rows for ID = 1 and Descp = 'One' has showed up more than once.

So an extra column* (i.e. MultipleOccurances (bool)) which has 1 for two rows with ID = 1 and Descp = 'One' and 0 for other rows as they are only showing up once.

How can I achieve that? (I want to avoid using Count(1)>1 or something if possible.

Edit:

Desired output:

ID  Descp   Extra   DuplicateRowNumber  IsMultiple
1   One     Extra1  1                   1
1   One     Extra4  2                   1
2   Two     Extra2  1                   0
3   Three   Extra3  1                   0

SQL Fiddle

like image 558
007 Avatar asked Mar 23 '23 21:03

007


2 Answers

You say "I want to avoid using Count" but it is probably the best way. It uses the partitioning you already have on the row_number

SELECT *,
       ROW_NUMBER() OVER (PARTITION BY ID, Descp 
                              ORDER BY (SELECT 0)) AS DuplicateRowNumber,
       CASE
         WHEN COUNT(*) OVER (PARTITION BY ID, Descp) > 1 THEN 1
         ELSE 0
       END                                         AS IsMultiple
FROM   #Temp 

And the execution plan just shows a single sort

plan

like image 73
Martin Smith Avatar answered Apr 06 '23 00:04

Martin Smith


Well, I have this solution, but using a Count...

SELECT T1.*, 
 ROW_NUMBER() OVER (PARTITION BY T1.ID, T1.Descp ORDER BY (SELECT 0))  AS DuplicateRowNumber,
 CASE WHEN T2.C = 1 THEN 0 ELSE 1 END MultipleOcurrences  FROM #temp T1
 INNER JOIN 
  (SELECT ID, Descp, COUNT(1) C FROM #TEMP GROUP BY ID, Descp) T2
  ON T1.ID = T2.ID AND T1.Descp = T2.Descp
like image 27
Ricardo Avatar answered Apr 05 '23 22:04

Ricardo