Dưới đây là ví dụ về cách xóa các hàng trùng lặp khỏi bảng trong MariaDB khi các hàng đó có khóa chính hoặc cột định danh duy nhất.
Các ví dụ xóa các hàng trùng lặp nhưng giữ lại một hàng. Vì vậy, trong trường hợp hai hàng giống nhau, nó sẽ xóa một trong số chúng và giữ lại hàng kia.
Dữ liệu mẫu
Các ví dụ của chúng tôi sử dụng dữ liệu sau:
SELECT * FROM Dogs;
Kết quả:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 2 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +-------+-----------+----------+
Chúng ta có thể thấy rằng hai hàng đầu tiên là trùng lặp, cũng như ba hàng cuối cùng.
DogId
cột chứa các giá trị duy nhất (vì đó là khóa chính của bảng) và do đó, nói một cách chính xác, không có bản sao. Nhưng trong các tình huống thực tế, bạn thường muốn loại bỏ các bảng có chứa khóa chính. Do đó, trong bài viết này, chúng tôi bỏ qua khóa chính và chúng tôi phát hiện các giá trị trùng lặp trên các cột còn lại.
Tùy chọn 1
Hãy bắt đầu tùy chọn đầu tiên của chúng tôi bằng cách chọn tất cả các hàng sẽ bị xóa:
SELECT * FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
Kết quả:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 2 | Bark | Smith | | 6 | Wag | Johnson | | 7 | Wag | Johnson | +-------+-----------+----------+
Để loại bỏ các hàng trùng lặp đó, chúng ta có thể chuyển đổi SELECT *
thành DELETE
:
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
Kết quả:
Query OK, 3 rows affected (0.017 sec)
Và để xác minh kết quả, chúng ta có thể chọn tất cả các hàng còn lại trong bảng:
SELECT * FROM Dogs;
Kết quả:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +-------+-----------+----------+
Chúng ta có thể sử dụng MAX()
một cách khác thay vì MIN()
chức năng thay đổi các hàng bị xóa.
Tùy chọn 2
Trong ví dụ này, chúng tôi sẽ giả định rằng bảng đã được khôi phục về trạng thái ban đầu (với các bản sao).
Chúng tôi có thể sử dụng truy vấn sau để kiểm tra các hàng trùng lặp:
SELECT *
FROM Dogs d1, Dogs d2
WHERE d1.FirstName = d2.FirstName
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId
AND d1.DogId = (
SELECT MAX(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
);
Kết quả:
+-------+-----------+----------+-------+-----------+----------+ | DogId | FirstName | LastName | DogId | FirstName | LastName | +-------+-----------+----------+-------+-----------+----------+ | 2 | Bark | Smith | 1 | Bark | Smith | | 7 | Wag | Johnson | 5 | Wag | Johnson | | 7 | Wag | Johnson | 6 | Wag | Johnson | +-------+-----------+----------+-------+-----------+----------+
Và chúng tôi có thể sửa đổi truy vấn đó để xóa các bản sao:
DELETE FROM Dogs WHERE DogId IN (
SELECT d2.DogId
FROM Dogs d1, Dogs d2
WHERE d1.FirstName = d2.FirstName
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId
AND d1.DogId=(
SELECT MIN(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
)
);
Kết quả:
Query OK, 3 rows affected (0.075 sec)
Bảng hiện đã được gỡ bỏ.
Chúng tôi có thể xác minh điều này bằng cách chọn lại tất cả các hàng:
SELECT * FROM Dogs;
Kết quả:
+-------+-----------+----------+ | DogId | FirstName | LastName | +-------+-----------+----------+ | 1 | Bark | Smith | | 3 | Woof | Jones | | 4 | Ruff | Robinson | | 5 | Wag | Johnson | +-------+-----------+----------+
Chúng tôi có thể sử dụng MAX()
thay vì MIN()
để xóa các hàng khác khỏi trùng lặp nếu muốn.