Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
MySQL + SQL · Lesson 141

Delete Duplicate Rows in MySQL

In this lesson: Remove duplicate records in MySQL and keep one copy using self join, ROW_NUMBER or temp table — with output. In Hindi & English.

The duplicate problem

Sometimes a table ends up with duplicate rows — the same customer or email entered twice. You usually want to keep one copy and delete the rest. MySQL offers a couple of clean ways to do this, and the golden rule is to find them first, then delete carefully.

💡 Find duplicates with GROUP BY, then delete the extras keeping one — always test first.

Find duplicates first

SELECT email, COUNT(*) AS copies
FROM users
GROUP BY email
HAVING COUNT(*) > 1;
+-------------------+--------+ | email | copies | +-------------------+--------+ | aman@example.com | 2 | +-------------------+--------+

GROUP BY the columns that define a duplicate, with HAVING COUNT(*) > 1. This shows which values are duplicated before you delete anything.

Delete with a self-join

DELETE t1
FROM users t1
JOIN users t2
  ON t1.email = t2.email
 AND t1.id > t2.id;

This joins the table to itself on the duplicate column, and deletes the row with the higher id whenever a lower-id row has the same email. The result: one copy (the lowest id) of each email survives.

The ROW_NUMBER way

DELETE FROM users
WHERE id IN (
    SELECT id FROM (
        SELECT id,
            ROW_NUMBER() OVER (PARTITION BY email ORDER BY id) AS rn
        FROM users
    ) t
    WHERE rn > 1
);

In MySQL 8.0+, ROW_NUMBER() numbers copies within each email group. Deleting where rn > 1 removes all but the first of each group — very clear and flexible.

Preventing future duplicates

ALTER TABLE users ADD UNIQUE (email);

After cleaning up, add a UNIQUE constraint so duplicates can never happen again. MySQL will reject any insert that would repeat an email, stopping the problem at the source.

Do it safely

  • Run the SELECT first to see exactly which rows will go.
  • Back up the table or use a transaction so you can ROLLBACK.
  • Double-check the keep rule (lowest id, newest date, etc.).

Deleting duplicates is destructive — a few seconds of checking prevents losing good data.

Common mistakes

  • Deleting without keeping one. The join condition must keep a copy.
  • Not testing first. Preview with a SELECT before deleting.
  • Forgetting to add UNIQUE. Without it, duplicates return.
  • Using ROW_NUMBER on old MySQL. Window functions need 8.0+.

Summary

  • Find duplicates with GROUP BY ... HAVING COUNT(*) > 1.
  • Delete extras with a self-join on id >, keeping the lowest id.
  • Or use ROW_NUMBER (MySQL 8.0+) to delete where rn > 1.
  • Add a UNIQUE constraint to prevent future duplicates.
  • Always test with a SELECT and use a transaction.

Next, practise a related query in finding employees with the same salary, or group data in GROUP BY and HAVING.

Frequently Asked Questions

How do I delete duplicate rows in MySQL but keep one?
A common way is a self-join that deletes rows with a higher id when another row has the same values: DELETE t1 FROM t t1 JOIN t t2 ON t1.email = t2.email AND t1.id > t2.id;. This keeps the lowest-id copy of each duplicate.
How do I find duplicate rows first?
Use GROUP BY on the columns that define a duplicate, with HAVING COUNT(*) > 1: SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1;. This lists the values that appear more than once.
What is the ROW_NUMBER method for removing duplicates?
In MySQL 8.0+, ROW_NUMBER() OVER (PARTITION BY the duplicate columns ORDER BY id) numbers copies within each group. You then delete rows where that number is greater than 1, keeping just the first of each group.
How do I prevent duplicate rows in the future?
Add a UNIQUE constraint on the column or columns that should be unique, like ALTER TABLE users ADD UNIQUE (email);. MySQL will then reject any insert that would create a duplicate.
Is it safe to delete duplicates directly?
Delete duplicates carefully: first run the matching SELECT to see what will be removed, and ideally back up the table or wrap the delete in a transaction so you can ROLLBACK. This avoids accidentally removing the wrong rows.
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

💻 Live Code Editor

This page's programs are ready here — run them, edit them, and learn. No installation needed.
Powered by OneCompiler. The code loads into the editor automatically — press Run to see the output. If the editor does not open, open it in a new tab.
Next topicEmployees with Same Salary Your progress: 141 / 151 (93%) · Lesson 142 / 151 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free