次のクエリを使用して、SQLiteで重複する行を返すことができます。
ここで、重複する行には、ID列を含むすべての列で重複する値が含まれています。
次のデータを含むテーブルがあるとします。
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行も重複しています。これは、3つの列すべてに、重複する各行に同じ値が含まれているためです。
次のクエリを使用して、重複している行の数を確認できます。
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>
ここでは、すべての列で行をグループ化し、各グループの行数を返しました。これにより、行が一意であるか(カウントが1)、重複しているか(カウントが1より大きい)がわかります。
カウントの降順で並べ替えることができるため、重複が最も多い行が最初に表示されます。
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
を使用できます。 カウントが1より大きい行のみを返す句
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
もう1つのオプションは、ROW_NUMBER()
を使用することです。 ウィンドウ関数:
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から始まります)。
上記のクエリを一般的なテーブル式として使用できます:
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
これにより、一致する重複から余分な行だけが返されます。したがって、同じ行が2つある場合は、そのうちの1つを返します。同一の行が3つある場合は、2つを返します。
このクエリは、重複排除操作でテーブルから削除される行数を示すのに役立ちます。他のいくつかのDBMS(少なくともSQL Serverでは)では、最後のSELECT *
を置き換えることができます DELETE
を使用 テーブルから重複する行を削除します。しかし、SQLiteではCTEをそのように更新することはできません。
幸い、次の2つのオプションは、削除を実行するように変更できます。
SQLiteのrowid
を利用できます :
SELECT * FROM Pets
WHERE EXISTS (
SELECT 1 FROM Pets p2
WHERE Pets.PetName = p2.PetName
AND Pets.PetType = p2.PetType
AND Pets.rowid > p2.rowid
);
結果:
PetId PetName PetType ----- ------- ------- 1 Wag Dog 4 Bark Dog 4 Bark Dog
これはどのように作動しますか?デフォルトでは、SQLiteのすべての行には、通常rowid
と呼ばれる特別な列があります 、テーブル内のその行を一意に識別します。これは必要に応じて削除できますが、明示的に削除されていない限り、クエリ内で活用できます。
そして最後に、SQLiteのrowid
を使用する別のオプションがあります :
SELECT * FROM Pets
WHERE rowid > (
SELECT MIN(rowid) FROM Pets p2
WHERE Pets.PetName = p2.PetName
AND Pets.PetType = p2.PetType
);
結果:
PetId PetName PetType ----- ------- ------- 1 Wag Dog 4 Bark Dog 4 Bark Dog