Ако имате таблица с дублиращи се редове в PostgreSQL, можете да използвате някоя от следните заявки, за да върнете дублиращите се редове.
Примерни данни
Да предположим, че имаме таблица със следните данни:
SELECT * FROM Pets;
Резултат:
petid | petname | pettype -------+---------+--------- 1 | Wag | Dog 1 | Wag | Dog 2 | Scratch | Cat 3 | Tweet | Bird 4 | Bark | Dog 4 | Bark | Dog 4 | Bark | Dog
Първите два реда са дублирани, а последните три реда са дублирани. Това е така, защото и трите колони съдържат едни и същи стойности във всеки дублиран ред.
Опция 1
Можем да използваме следната заявка, за да видим колко реда са дублирани:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY PetId;
Резултат:
petid | petname | pettype | Count -------+---------+---------+------- 1 | Wag | Dog | 2 2 | Scratch | Cat | 1 3 | Tweet | Bird | 1 4 | Bark | Dog | 3
Алтернативно можем да го подредим по брой в низходящ ред, така че редовете с най-много дубликати да се показват първи:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY Count(*) DESC;
Резултат:
petid | petname | pettype | Count -------+---------+---------+------- 4 | Bark | Dog | 3 1 | Wag | Dog | 2 2 | Scratch | Cat | 1 3 | Tweet | Bird | 1
Опция 2
Можем да използваме HAVING
клауза, ако искаме само изброените дублиращи се редове:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
HAVING COUNT(*) > 1
ORDER BY PetId;
Резултат:
petid | petname | pettype | Count -------+---------+---------+------- 1 | Wag | Dog | 2 4 | Bark | Dog | 3
Опция 3
Друга възможност е да използвате ROW_NUMBER()
на Postgres функция на прозореца:
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS Row_Number
FROM Pets;
Резултат:
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
клауза разделя резултатния набор, произведен от FROM
клауза в дялове, към които се прилага функцията. Когато посочим дялове за набора от резултати, всеки дял кара номерирането да започне отново (т.е. номерирането ще започне от 1 за първия ред във всеки дял).
Опция 4
Можем да използваме горната заявка като общ табличен израз, за да върнем само излишните редове от съответстващите дубликати:
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;
Резултат:
petid | petname | pettype | row_number -------+---------+---------+------------ 1 | Wag | Dog | 2 4 | Bark | Dog | 2 4 | Bark | Dog | 3