Problems / Keep the Latest Record / Editorial
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC). The newest row per user gets rn = 1; a user with a single row trivially gets rn = 1 too.
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY updated_at DESC)
rn = 1
WHERE
rn
WHERE rn = 1
user_id
```sql
SELECT p.user_id, p.email, p.city, p.updated_at
FROM profile_updates p
JOIN (
SELECT user_id, MAX(updated_at) AS max_at
FROM profile_updates
GROUP BY user_id
) m ON p.user_id = m.user_id AND p.updated_at = m.max_at
```
This is correct here only because updated_at is unique within each user. If two updates could share a timestamp, the join would return both rows, while ROW_NUMBER (with an extra tiebreaker in the ORDER BY) still returns exactly one.
updated_at
ROW_NUMBER
ORDER BY
"Keep the latest record per key" is the workhorse of change-log compaction — it's how you turn an event-sourced history into current state, and it's the same pattern warehouses use to deduplicate late-arriving or reprocessed data. The classic mistakes: reaching for DISTINCT (does nothing — the rows differ), or aggregating each column independently (MAX(email), MAX(city)), which can stitch together a frankenrow from *different* updates (user 3's alphabetically-largest email is not their newest one). ROW_NUMBER ... DESC + rn = 1 keeps whole rows intact, which is exactly what a snapshot needs.
DISTINCT
MAX(email)
MAX(city)
ROW_NUMBER ... DESC
Solve Keep the Latest Record yourself →