Question presented to candidate: "We found duplicate subscribers: the same email signed up two or three times. Write the SQL to delete the duplicates but keep exactly one row per email. How do you choose which one survives, and how would you do it safely on a big production table?"
What a strong answer should cover:
- Decide the survivor rule first (oldest id, newest row, most complete row) and make it deterministic with a tie-breaker
- Pattern 1:
DELETE ... WHERE id NOT IN (SELECT MIN(id) ... GROUP BY key); pattern 2:ROW_NUMBER() OVER (PARTITION BY key ORDER BY ...)and deletern > 1 - NULL keys:
GROUP BYlumps all NULLs together, so a careless query deletes rows that are not duplicates - Tables without a key: SQLite
rowid, PostgreSQLctid, or copy the distinct rows into a new table - Engine detail: PostgreSQL
DELETE ... USINGandRETURNING; MySQL rejects a subquery on the target table (error 1093) unless it is wrapped in a derived table - Safety: preview with a
SELECTfirst, run in a transaction, batch large deletes, then add aUNIQUEconstraint
Clarifying questions expected:
- Which copy should we keep: the first sign-up, the latest, or the one with the most data?
- Do other tables reference these rows through foreign keys (do child rows need re-pointing first)?
- How big is the table, and can it be locked or must the delete run while traffic continues?
Code / implementation expected: Yes β a DELETE that keeps one row per group, with the survivor chosen by MIN(id) or ROW_NUMBER().
Schema used by the examples: