以下は、SQLiteのテーブルから重複する行が主キーまたは一意の識別子列を持っている場合にそれらの行を削除する6つの例です。
このような場合、重複を比較するときは主キーを無視する必要があります(主キーは定義上重複行を防ぐため)。
この例では、次のデータを使用しています。
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
最後の3行と同様に、最初の2行に重複が含まれていることがわかります。
DogId
列は一意の値を保持するため(テーブルの主キーであるため)、厳密に言えば、重複はありません。しかし、実際の状況では、主キーを含むテーブルの重複を排除したい場合がよくあります。したがって、次の例では、主キーを無視し、残りの列で重複する値を含む行を削除します。
上記の表を重複排除するための最初のオプションは次のとおりです。
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
EXCEPT SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
テーブルは期待どおりに重複排除されています。
または、MAX()
を使用することもできます MIN()
の代わりに関数 削除する行を変更する関数。次の例でこれを行います。
この例(および次の例)では、テーブルが(重複して)元の状態に復元されていると想定します。
重複する行を削除して残りの行を選択する別のクエリは次のとおりです。
DELETE FROM Dogs WHERE DogId IN (
SELECT d2.DogId
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
)
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 2 Bark Smith 3 Woof Jones 4 Ruff Robinson 7 Wag Johnson
これで、テーブルの重複が解除されました。
MAX()
を使用したことに注意してください MIN()
の代わりに関数 前の例で使用しました。これが重複排除操作に与える影響を確認できます。テーブルからさまざまな行を削除しました。
MIN()
を使用する必要のないオプションは次のとおりです またはMAX()
:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.DogId > d2.DogId
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
別のオプションは次のとおりです:
DELETE FROM Dogs
WHERE DogId > (
SELECT MIN(DogId) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
デフォルトでは、SQLiteのすべての行には、通常rowid
と呼ばれる特別な列があります 、テーブル内のその行を一意に識別します。テーブルから明示的に削除されていない限り、これを各行の一意の識別子として使用できます。この方法は、何らかの理由で主キーを参照できない場合(または、テーブルに主キーがない場合)に役立つ可能性があります。
したがって、rowid
を使用できます DogId
の代わりにクエリで 列:
DELETE FROM Dogs
WHERE EXISTS (
SELECT 1 FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
AND Dogs.rowid > d2.rowid
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson
これが他の例ですが、rowid
主キーの代わりに:
DELETE FROM Dogs
WHERE rowid > (
SELECT MIN(rowid) FROM Dogs d2
WHERE Dogs.FirstName = d2.FirstName
AND Dogs.LastName = d2.LastName
);
SELECT * FROM Dogs;
結果:
DogId FirstName LastName ----- --------- -------- 1 Bark Smith 3 Woof Jones 4 Ruff Robinson 5 Wag Johnson