Các truy vấn sau có thể được sử dụng để trả về các hàng trùng lặp trong SQLite.
Tại đây, các hàng trùng lặp chứa các giá trị trùng lặp trên tất cả các cột, bao gồm cả cột ID.
Dữ liệu Mẫu
Giả sử chúng ta có một bảng với dữ liệu sau:
SELECT * FROM Pets;
Kết quả:
PetId PetName PetType ----- ------- ------- 1 Wag Dog 1 Wag Dog 2 Scratch Cat 3 Tweet Bird 4 Bark Dog 4 Bark Dog 4 Bark Dog
Hai hàng đầu tiên trùng lặp, ba hàng cuối cùng cũng vậy. Đó là vì cả ba cột đều chứa các giá trị giống nhau trong mỗi hàng trùng lặp.
Tùy chọn 1
Chúng ta có thể sử dụng truy vấn sau để xem có bao nhiêu hàng trùng lặp:
CHỌN PetId, PetName, PetType, COUNT (*) AS "Count" FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY PetId;
Kết quả:
PetId PetName PetType Count ----- ------- ------- ----- 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bark Dog 3
Ở đây, chúng tôi đã nhóm các hàng theo tất cả các cột và trả về số hàng của mỗi nhóm. Điều này cho chúng ta biết liệu một hàng là duy nhất (với số lượng là 1) hay là hàng trùng lặp (với số lượng lớn hơn 1).
Chúng tôi có thể sắp xếp nó theo số lượng theo thứ tự giảm dần, để các hàng có nhiều bản sao nhất xuất hiện đầu tiên:
CHỌN PetId, PetName, PetType, COUNT (*) AS "Count" FROM PetsGROUP BY PetId, PetName, PetTypeORDER BY Count (*) DESC;
Kết quả:
PetId PetName PetType Count ----- ------- ------- ----- 4 Bark Dog 3 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1
Tùy chọn 2
Nếu chúng ta chỉ muốn các hàng trùng lặp được liệt kê, chúng ta có thể sử dụng HAVING
mệnh đề chỉ trả về các hàng có tổng số lớn hơn 1:
CHỌN PetId, PetName, PetType, COUNT (*) AS "Count" TỪ PetsGROUP BY PetId, PetName, PetTypeHAVING COUNT (*)> 1ORDER BY PetId;
Kết quả:
PetId PetName PetType Count ----- ------- ------- ----- 1 Wag Dog 2 4 Bark Dog 3
Tùy chọn 3
Một tùy chọn khác là sử dụng ROW_NUMBER ()
chức năng cửa sổ:
SELECT *, ROW_NUMBER () OVER (PHẦN BỞI PetId, PetName, PetType ORDER BY PetId, PetName, PetType) AS Row_NumberFROM Pets;
Kết quả:
PetId PetName PetType Row_Number ------------ 1 Wag Dog 1 1 Wag Dog 2 2 Scratch Cat 1 3 Tweet Bird 1 4 Bark Dog 1 4 Bark Dog 2 4 Bark Dog 3
PARTITION BY
mệnh đề chia tập kết quả được tạo ra bởi FROM
mệnh đề thành các phân vùng mà hàm được áp dụng. Khi chúng ta chỉ định phân vùng cho tập kết quả, mỗi phân vùng sẽ làm cho việc đánh số bắt đầu lại (tức là việc đánh số sẽ bắt đầu từ 1 cho hàng đầu tiên trong mỗi phân vùng).
Tùy chọn 4
Chúng ta có thể sử dụng truy vấn trên làm biểu thức bảng chung:
WITH cte AS (SELECT *, ROW_NUMBER () OVER (PARTITION BY PetId, PetName, PetType ORDER BY PetId, PetName, PetType) AS Row_Number FROM Pets) CHỌN * TỪ cte WHERE Row_Number <> 1;
Kết quả:
PetId PetName PetType Row_Number ------------ 1 Wag Dog 2 4 Bark Dog 2 4 Bark Dog 3Điều này chỉ trả về các hàng thừa từ các bản sao phù hợp. Vì vậy, nếu có hai hàng giống nhau, nó trả về một trong số chúng. Nếu có ba hàng giống nhau, nó trả về hai, v.v.
Truy vấn này có thể hữu ích để hiển thị số hàng sẽ bị xóa khỏi bảng trong một hoạt động loại bỏ lỗi. Trong một số DBMS khác (ít nhất là trong SQL Server), chúng ta có thể thay thế
SELECT *
cuối cùng vớiDELETE
để xóa các hàng trùng lặp khỏi bảng. Nhưng SQLite sẽ không cho phép chúng tôi cập nhật CTE như vậy.May mắn thay, hai tùy chọn tiếp theo có thể được sửa đổi để thực hiện xóa.
Tùy chọn 5
Chúng ta có thể tận dụng
rowid
của SQLite :SELECT * FROM PetsWHERE TỒN TẠI (CHỌN 1 TỪ Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType AND Pets.rowid> p2. rowid);
Kết quả:
PetId PetName PetType ----- ------- ------- 1 Wag Dog 4 Bark Dog 4 Bark DogCái này hoạt động ra sao? Theo mặc định, mỗi hàng trong SQLite có một cột đặc biệt, thường được gọi là
rowid
, xác định duy nhất hàng đó trong bảng. Điều này có thể được xóa nếu được yêu cầu, nhưng trừ khi nó đã được xóa rõ ràng, bạn sẽ có thể tận dụng nó trong các truy vấn của mình.Tùy chọn 6
Và cuối cùng, đây là một tùy chọn khác sử dụng
rowid
của SQLite :SELECT * FROM PetsWHERE rowid> (SELECT MIN (rowid) FROM Pets p2 WHERE Pets.PetName =p2.PetName AND Pets.PetType =p2.PetType);
Kết quả:
PetId PetName PetType ----- ------- ------- 1 Wag Dog 4 Bark Dog 4 Bark Dog