Nếu bạn có một bảng có các hàng trùng lặp trong PostgreSQL, bạn có thể sử dụng bất kỳ truy vấn nào sau đây để trả về các hàng trùng lặp.
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 là bản sao và ba hàng cuối cùng là bản sao. Đó 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:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER 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
Ngoài ra, 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:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER 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
Chúng ta có thể sử dụng HAVING
nếu chúng ta chỉ muốn các hàng trùng lặp được liệt kê:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
HAVING COUNT(*) > 1
ORDER 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()
của Postgres chức năng cửa sổ:
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM 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 thông thường để chỉ trả về các hàng thặng dư từ các bản sao phù hợp:
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM Pets
)
SELECT * FROM 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