これらの行に主キーまたはその他の一意の識別子列がある場合にSQLiteで重複行を返すための11のオプションがあります(ただし、主キーを無視したい場合)。
これは、重複する行が、主キー/一意のID列を除いて、すべての列でまったく同じ値を共有することを意味します。
サンプルデータ
例では、次のデータを使用します。
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson 6 Wag Johnson 7 Wag Johnson
最初の2行は重複しています(DogId
を除く) 列。これはテーブルの主キーであり、すべての行にわたって一意の値が含まれています)。最後の3行も重複しています(DogId
を除く) 列)。
主キーの列は、重複する行がないことを保証します。これは、主キーがデータの整合性を強化するのに役立つため、RDBMSでは適切な方法です。ただし、主キーは行の重複を防ぐため、重複を見つける機能を妨げる可能性があります。
上記の表では、主キー列は増分番号であり、その値は意味を持たず、重要ではありません。したがって、他の列で重複を見つけたい場合は、その行を無視する必要があります。
オプション1
GROUP BY
を使用してクエリを実行できます 列を重要な列でグループ化するには、COUNT()
を使用します。 同一の行数を返す関数:
SELECT
FirstName,
LastName,
COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
ORDER BY Count DESC;
結果:
FirstName LastName Count --------- -------- ----- Wag Johnson 3 Bark Smith 2 Ruff Robinson 1 Woof Jones 1
ここでは、クエリから主キー列を省略して除外しました。また、重複が最初に表示されるように、カウントの降順で並べ替えました。
結果は、Wag Johnsonを含む3つの行と、BarkSmithを含む2つの行があることを示しています。これらは重複しています(またはWag Johnsonの場合は3回)。他の2つの行には重複がありません。
オプション2
HAVING
を使用できます 非重複を出力から除外する句:
SELECT
FirstName,
LastName,
COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName, LastName
HAVING COUNT(*) > 1
ORDER BY Count DESC;
結果:
FirstName LastName Count --------- -------- ----- Wag Johnson 3 Bark Smith 2
オプション3
連結された列の重複をチェックする例を次に示します。この場合、DISTINCT
を使用します キーワードを使用して個別の値を取得し、COUNT()
を使用します カウントを返す関数:
SELECT
DISTINCT FirstName || ' ' || LastName AS DogName,
COUNT(*) AS Count
FROM Dogs
GROUP BY FirstName || ' ' || LastName
ORDER BY Count DESC;
結果:
DogName Count ------------- ----- Wag Johnson 3 Bark Smith 2 Woof Jones 1 Ruff Robinson 1
オプション4
デフォルトでは、SQLiteのすべての行には、通常rowid
と呼ばれる特別な列があります。 、テーブル内のその行を一意に識別します。テーブルから明示的に削除されていない限り、これを各行の一意の識別子として使用できます。
したがって、rowid
を使用できます クエリで:
SELECT * FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.rowid > d2.rowid
);
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag Johnson
SELECT *
を置き換えることができます DELETE
を使用 テーブルに対して重複排除操作を実行します。
DogId
を使用できた可能性があることに注意してください rowid
の代わりにcolumn(主キー) 必要に応じて。そうは言っても、rowid
何らかの理由で主キー列を使用できない場合、またはテーブルに主キーがない場合に役立ちます。
オプション5
rowid
を使用する別のクエリを次に示します。 :
SELECT * FROM Dogs
WHERE rowid > (
SELECT MIN(rowid) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag Johnson
前の例と同様に、SELECT *
を置き換えることができます DELETE
を使用 重複する行を削除します。
オプション6
2つのrowid
上記のオプションは、クエリで主キーを完全に無視する必要がある場合(または、主キー列がまったくない場合)に最適です。ただし、前述のように、rowid
を置き換えるオプションはまだあります。 主キー列を使用–この場合はDogId
列:
SELECT * FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.DogId > d2.DogId
);
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag Johnson
オプション7
そして、これがrowid
を使用したもう1つのクエリです。 DogId
に置き換えられました 列:
SELECT * FROM Dogs
WHERE DogId > (
SELECT MIN(DogId) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag Johnson
オプション8
これを行う別の方法は、ROW_NUMBER()
を使用することです。 ウィンドウ関数:
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY FirstName, LastName
ORDER BY FirstName, LastName
) AS Row_Number
FROM Dogs;
結果:
DogId FirstName LastName Row_Number ----- --------- -------- ---------- 1 Bark Smith 1 2 Bark Smith 2 4 Ruff Robinson 1 5 Wag Johnson 1 6 Wag Johnson 2 7 Wag Johnson 3 3 Woof Jones 1
PARTITION
の使用 句を指定すると、新しい列が追加され、重複するたびに行番号が増加しますが、一意の行があると再びリセットされます。
この場合、結果はグループ化されません。つまり、一意の識別子列を含む、重複する各行を確認できます。
オプション9
前の例を、より大きなクエリの一般的なテーブル式として使用することもできます。
WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (
PARTITION BY FirstName, LastName
ORDER BY FirstName, LastName
) AS Row_Number
FROM Dogs
)
SELECT * FROM cte WHERE Row_Number <> 1;
結果:
DogId FirstName LastName Row_Number ----- --------- -------- ---------- 2 Bark Smith 2 6 Wag Johnson 2 7 Wag Johnson 3
これにより、非重複が出力から除外され、各重複の1行が出力から除外されます。
オプション10
前の例と同じ出力を取得する別の方法は次のとおりです。
SELECT * FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 6 Wag Johnson 7 Wag Johnson
オプション11
テーブルから重複を選択するためのさらに別のオプションは次のとおりです。
SELECT *
FROM Dogs d1, Dogs d2
WHERE d1.FirstName = d2.FirstName
AND d1.LastName = d2.LastName
AND d1.DogId <> d2.DogId
AND d1.DogId = (
SELECT MAX(DogId)
FROM Dogs d3
WHERE d3.FirstName = d1.FirstName
AND d3.LastName = d1.LastName
);
結果:
DogId FirstName LastName DogId FirstName LastName ----- --------- -------- ----- --------- -------- 2 Bark Smith 1 Bark Smith 7 Wag Johnson 5 Wag Johnson 7 Wag Johnson 6 Wag Johnson