Solving tips
- Deduplication means one row per key: PARTITION BY the dedup key, ORDER BY your recency/tie-break rule, and keep the row where ROW_NUMBER = 1.
- Put ROW_NUMBER in a subquery or CTE, then filter on it — you cannot reference a window alias inside WHERE in the same SELECT.
- Make ORDER BY fully deterministic (add a unique tie-break like id) or which duplicate survives becomes arbitrary.
A contacts table has accumulated duplicate rows for the same email. You need to keep exactly one record per email — the most recently updated one — and drop the rest.
Schema
CREATE TABLE contacts (
id INT PRIMARY KEY,
email TEXT,
full_name TEXT,
updated_at TIMESTAMP
);
| id | full_name | updated_at | |
|---|---|---|---|
| 1 | ann@x.com | Ann Lee | 2024-01-10 09:00:00 |
| 2 | bob@x.com | Bob Ray | 2024-01-11 10:00:00 |
| 3 | ann@x.com | Ann M Lee | 2024-02-01 08:30:00 |
| 4 | cara@x.com | Cara Kim | 2024-01-05 12:00:00 |
| 5 | bob@x.com | Robert Ray | 2024-03-02 14:15:00 |
| 6 | ann@x.com | Ann Lee | 2024-01-20 07:45:00 |
Task
Return one row per email: the one with the latest updated_at. Break ties on updated_at by keeping the highest id. Output columns id, email, full_name, updated_at, ordered by email ascending.
Expected output
| id | full_name | updated_at | |
|---|---|---|---|
| 3 | ann@x.com | Ann M Lee | 2024-02-01 08:30:00 |
| 5 | bob@x.com | Robert Ray | 2024-03-02 14:15:00 |
| 4 | cara@x.com | Cara Kim | 2024-01-05 12:00:00 |