Interview Question of the Week #014 – How to DELETE Duplicate Rows

This is another interview question I hear often: how would you delete duplicate rows when the table has an identity column? I have to look up the exact syntax myself sometimes. The important part is deciding which row is the duplicate before writing DELETE.

One intact ceramic tile from each matching pair is kept in a tray while its worn duplicate is set aside

Question: How do you delete duplicate rows in SQL Server when the table has an identity column?

Answer: First name the columns that define a duplicate. In my original example they were DuplicateColumn1, DuplicateColumn2, and DuplicateColumn3. Keep the row with the largest non-NULL identity ID in each group, and inspect the rows that would be removed:

SELECT ID, DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
FROM dbo.MyTable
WHERE ID NOT IN
(
    SELECT MAX(ID)
    FROM dbo.MyTable
    GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
);

If that result is exactly the set of unwanted rows, the original deletion pattern is:

DELETE FROM dbo.MyTable
WHERE ID NOT IN
(
    SELECT MAX(ID)
    FROM dbo.MyTable
    GROUP BY DuplicateColumn1, DuplicateColumn2, DuplicateColumn3
);

Use a transaction and check the preview and affected row count before committing a change to real data. This example assumes ID is a non-NULL, unique identity. The largest ID is a chosen survivor, not proof that it is the most recently created or most correct row. Check foreign keys and the actual business rule too: matching values can represent legitimate separate events.

When the survivor rule is more complicated, ROW_NUMBER() lets you partition by the duplicate columns and order by the row you want to keep. Keep the original answer simple for this particular interview question, then explain why the rule must be explicit.

I also recorded a short video showing this approach.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

Previous Post
Interview Question of the Week #013 – Stored Procedure and Its Advantages – How to Create Stored Procedure
Next Post
Interview Question of the Week #015 – How to Move TempDB to Different Drive

Related Posts

No results found.

8 Comments. Leave new

  • Hi sir,
    I believe that this script is good where there is primary key in table. When there is no primary key in table the approach should be changed.

    Please provide clarification and best approach.

    Reply
    • Create a serial number using row_number() function and delete the duplicates

      delete t from (select *,row_number() over (partition by keycol order by keycol) as sno from table) as t where sno>1

      Reply
  • Hi,

    I have a table where there is no any identity column or any unique column and i want delete duplicate rows. Please help. This table contains about 30 millions data.

    Reply
    • Create a serial number using row_number() function and delete the duplicates

      delete t from (select *,row_number() over (partition by keycol order by keycol) as sno from table) as t where sno>1

      Reply
  • mekalanaresh0404
    April 6, 2015 10:31 am

    Hi pinal,

    I tried above script to delete my duplicate data,but I could not delete my data.
    we can delete duplicate data using cte expression thats easy and fast.

    Reply
  • mekalanaresh0404
    April 6, 2015 10:31 am

    Hi pinal,

    I tried above script to delete my duplicate data,but I could not delete my data.
    we can delete duplicate data using cte expression thats easy and fast.

    Reply
  • mekalanaresh0404
    April 6, 2015 10:41 am

    WITH CTE AS(
    SELECT id,name,ROW_NUMBER()OVER(PARTITION BY id ORDER BY id)as rn
    FROM dupdata
    )
    DELETE FROM CTE WHERE rn > 1

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.