MySQLテーブルに重複する行があると思われる場合は、次のオプションを使用してすべての重複を返すことができます。
次のデータを含むテーブルがあるとします。
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 | +-------+---------+---------+
最初の2行は重複しており、最後の3行も重複しています。重複する行は、すべての列で同じ値を共有します。
1つのオプションは、次のクエリを使用して重複する行を返すことです。
SELECT
DISTINCT PetId,
COUNT(*) AS "Count"
FROM Pets
GROUP BY PetId
ORDER BY PetId;
結果:
+-------+-------+ | PetId | Count | +-------+-------+ | 1 | 2 | | 2 | 1 | | 3 | 1 | | 4 | 3 | +-------+-------+
SELECT
を展開できます 必要に応じて列を追加するリスト:
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 | +-------+---------+---------+-------+
重複する行のみを一覧表示する場合は、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 | +-------+---------+---------+-------+
これを行う別の方法は、ROW_NUMBER()
を使用することです。 PARTITION BY
で機能する 結果セットの出力に番号を付ける句。
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY PetId, PetName, PetType
ORDER BY PetId, PetName, PetType
) AS rn
FROM Pets;
結果:
+-------+---------+---------+----+ | 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
句は、FROM
によって生成された結果セットを分割します 関数が適用されるパーティションへの句。結果セットにパーティションを指定すると、各パーティションによって番号付けが最初からやり直されます(つまり、各パーティションの最初の行の番号付けは1から始まります)。
一致する重複から余剰行だけを返すには、次のように、上記のクエリを一般的なテーブル式として使用できます。
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;
結果:
+-------+---------+---------+----+ | PetId | PetName | PetType | rn | +-------+---------+---------+----+ | 1 | Wag | Dog | 2 | | 4 | Bark | Dog | 2 | | 4 | Bark | Dog | 3 | +-------+---------+---------+----+