How do you delete duplicate rows, keeping one copy?
Quick Answer
Use ROW_NUMBER() in a CTE partitioned by the duplicate key, then DELETE FROM cte WHERE rn > 1. SQL Server lets you DELETE directly from a CTE, which removes the corresponding base-table rows. The ORDER BY in the window picks which copy survives.
I number the rows with ROW_NUMBER() partitioned by whatever makes them duplicates, inside a CTE, and then DELETE FROM the_cte WHERE rn > 1 — SQL Server propagates that delete to the base table. The ORDER BY in the window decides which one I keep, usually the lowest id or the most complete record. I'd run it in a transaction, check the row count first, and afterwards add a unique constraint so the duplicates can't come back. On a large table I'd batch it in chunks.
WITH D AS (
SELECT *, ROW_NUMBER() OVER (
PARTITION BY Email
ORDER BY Id) AS rn
FROM Users
)
DELETE FROM D WHERE rn > 1;- Take a backup / run in a transaction and check the count first.
- Add every column that defines a “true duplicate” to the
PARTITION BY. - Afterwards, add a
UNIQUEconstraint / index so it can't happen again. - For huge tables, batch the delete (
DELETE TOP (10000) ...in a loop) to control the log and locking.