Learn SQL/Advanced/Interview Patterns/SQL Remove Duplicate Rows

SQL Remove Duplicate Rows

Find them first (previous lesson), then use ROW_NUMBER to keep exactly one copy of each.

What & Why

Finding duplicates tells you a problem exists. Removing them needs ROW_NUMBER() PARTITION BY the duplicate-defining columns, then keeping only rn = 1 — the exact deduplication pattern from the Window Functions series.

See How It Works

BUSINESS QUESTION

Marketing wants one latest lead row per normalized email.

idcampaign_idemailcreated_atqualified_atconverted_atlead_scoresourcecountry
3011ana@example.com2024-01-21 09:10:00+002024-01-22 11:00:00+002024-02-02 10:00:00+0086google_adsUS
3021ben@example.com2024-01-24 12:40:00+00NULLNULL52google_adsCA
3032chloe@example.com2024-02-16 08:30:00+002024-02-18 14:20:00+00NULL74emailGB
3043dev@example.com2024-03-20 17:15:00+002024-03-21 09:00:00+002024-04-04 16:00:00+0091linkedinUS
EXAMPLE QUERY
WITH ranked AS (
  SELECT
    id AS lead_id,
    LOWER(email) AS normalized_email,
    created_at,
    ROW_NUMBER() OVER (PARTITION BY LOWER(email) ORDER BY created_at DESC, id DESC) AS duplicate_rank
  FROM marketing.leads
)
SELECT lead_id, normalized_email, created_at
FROM ranked
WHERE duplicate_rank = 1
ORDER BY normalized_email;
RESULT — latest row per email
lead_idnormalized_emailcreated_at
301ana@example.com2024-01-21 09:10:00+00
302ben@example.com2024-01-24 12:40:00+00
303chloe@example.com2024-02-16 08:30:00+00
304dev@example.com2024-03-20 17:15:00+00

All representative lead emails are unique, so each row is its partition's latest.

This lesson's practice is part of Pro.

Advanced business practice

Sign up free to try it on a real business scenario