Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MySQL

Tìm tất cả các hàng trùng lặp dựa trên một hoặc hai cột trong MySQL

Để tìm các hàng trùng lặp (duplicate) theo một hoặc nhiều cột, phương pháp phổ biến là dùng truy vấn con (subquery) với GROUP BY và HAVING COUNT(*) > 1 để xác định các giá trị trùng, sau đó chọn các hàng có giá trị đó.

Tạo bảng và dữ liệu

mysql> CREATE TABLE DemoTable (
    StudentId INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    StudentFirstName VARCHAR(20),
    StudentLastName VARCHAR(20)
);

mysql> INSERT INTO DemoTable (StudentFirstName, StudentLastName) VALUES
('John', 'Smith'), ('Carol', 'Taylor'), ('John', 'Doe'), ('John', 'Brown'), ('David', 'Miller');

Dữ liệu (John xuất hiện 3 lần với LastName khác nhau)

mysql> SELECT * FROM DemoTable;
+-----------+------------------+-----------------+
| StudentId | StudentFirstName | StudentLastName |
+-----------+------------------+-----------------+
|         1 | John             | Smith           |
|         2 | Carol            | Taylor          |
|         3 | John             | Doe             |
|         4 | John             | Brown           |
|         5 | David            | Miller          |
+-----------+------------------+-----------------+

Truy vấn tìm ID các hàng trùng FirstName (xuất hiện > 1 lần)

mysql> SELECT StudentId FROM DemoTable 
WHERE StudentFirstName IN (
    SELECT StudentFirstName FROM DemoTable 
    GROUP BY StudentFirstName 
    HAVING COUNT(*) > 1
);

Kết quả

+-----------+
| StudentId |
+-----------+
|         1 |
|         3 |
|         4 |
+-----------+

Cách tốt hơn: Dùng JOIN (hiệu năng cao hơn)

SELECT d1.StudentId, d1.StudentFirstName, d1.StudentLastName
FROM DemoTable d1
JOIN (
    SELECT StudentFirstName 
    FROM DemoTable 
    GROUP BY StudentFirstName 
    HAVING COUNT(*) > 1
) d2 ON d1.StudentFirstName = d2.StudentFirstName;

Tìm trùng lặp theo 2 cột (FirstName + LastName)

SELECT StudentFirstName, StudentLastName, COUNT(*) as cnt
FROM DemoTable
GROUP BY StudentFirstName, StudentLastName
HAVING COUNT(*) > 1;

Nếu kết quả rỗng -> không có cặp (FirstName, LastName) nào trùng.

Mẹo xóa trùng lặp (giữ 1): MySQL 8.0+ dùng ROW_NUMBER() window function. Phiên bản cũ dùng self-join delete.