Jeśli uważasz, że tabela MySQL może mieć zduplikowane wiersze, możesz użyć następujących opcji, aby zwrócić wszystkie duplikaty.
Przykładowe dane
Załóżmy, że mamy tabelę z następującymi danymi:
SELECT * FROM Pets;
Wynik:
+-------+---------+---------+ | PetId | PetName | PetType | +-------+---------+---------+ | 1 | Wag | Dog | | 1 | Wag | Dog | | 2 | Scratch | Cat | | 3 | Tweet | Bird | | 4 | Bark | Dog | | 4 | Bark | Dog | | 4 | Bark | Dog | +-------+---------+---------+
Pierwsze dwa wiersze są duplikatami, podobnie jak ostatnie trzy wiersze. Zduplikowane wiersze mają te same wartości we wszystkich kolumnach.
Opcja 1
Jedną z opcji jest użycie następującego zapytania w celu zwrócenia zduplikowanych wierszy:
SELECT
DISTINCT PetId,
COUNT(*) AS "Count"
FROM Pets
GROUP BY PetId
ORDER BY PetId;
Wynik:
+-------+-------+ | PetId | Count | +-------+-------+ | 1 | 2 | | 2 | 1 | | 3 | 1 | | 4 | 3 | +-------+-------+
Możemy rozwinąć SELECT
lista zawierająca więcej kolumn, jeśli jest to wymagane:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY PetId;
Wynik:
+-------+---------+---------+-------+ | PetId | PetName | PetType | Count | +-------+---------+---------+-------+ | 1 | Wag | Dog | 2 | | 2 | Scratch | Cat | 1 | | 3 | Tweet | Bird | 1 | | 4 | Bark | Dog | 3 | +-------+---------+---------+-------+
Możemy sprawić, by duplikaty pojawiły się jako pierwsze, porządkując je według liczby w kolejności malejącej:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
ORDER BY Count DESC;
Wynik:
+-------+---------+---------+-------+ | PetId | PetName | PetType | Count | +-------+---------+---------+-------+ | 4 | Bark | Dog | 3 | | 1 | Wag | Dog | 2 | | 2 | Scratch | Cat | 1 | | 3 | Tweet | Bird | 1 | +-------+---------+---------+-------+
Opcja 2
Jeśli chcemy wyświetlić tylko zduplikowane wiersze, możemy użyć HAVING
klauzula wykluczająca nieduplikaty z danych wyjściowych:
SELECT
PetId,
PetName,
PetType,
COUNT(*) AS "Count"
FROM Pets
GROUP BY
PetId,
PetName,
PetType
HAVING COUNT(*) > 1
ORDER BY PetId;
Wynik:
+-------+---------+---------+-------+ | PetId | PetName | PetType | Count | +-------+---------+---------+-------+ | 1 | Wag | Dog | 2 | | 4 | Bark | Dog | 3 | +-------+---------+---------+-------+
Opcja 3
Innym sposobem na to jest użycie ROW_NUMBER()
funkcja z PARTITION BY
klauzula do numerowania danych wyjściowych zestawu wyników.
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS rn
FROM Pets;
Wynik:
+-------+---------+---------+----+ | PetId | PetName | PetType | rn | +-------+---------+---------+----+ | 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
klauzula dzieli zbiór wyników utworzony przez FROM
klauzuli na przegrody, do których funkcja jest stosowana. Kiedy określamy partycje dla zestawu wyników, każda partycja powoduje, że numeracja zaczyna się od nowa (tj. numeracja rozpocznie się od 1 dla pierwszego wiersza w każdej partycji).
Opcja 4
Aby zwrócić tylko nadwyżki wierszy z pasujących duplikatów, możemy użyć powyższego zapytania jako wspólnego wyrażenia tabelowego, na przykład:
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS rn
FROM Pets
)
SELECT * FROM cte WHERE rn <> 1;
Wynik:
+-------+---------+---------+----+ | PetId | PetName | PetType | rn | +-------+---------+---------+----+ | 1 | Wag | Dog | 2 | | 4 | Bark | Dog | 2 | | 4 | Bark | Dog | 3 | +-------+---------+---------+----+