これらの行に主キーまたは一意の識別子列がある場合に、OracleDatabaseの表から重複する行を削除するためのいくつかのオプションを次に示します。
このような場合、重複する行を比較するときは主キーを無視する必要があります(主キーは一意の値を保持しているため)。
この例では、次のデータを使用しています。
SELECT * FROM Dogs;
結果:
DOGID | FIRSTNAME | 姓 |
---|---|---|
1 | バーク | スミス |
2 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |
6 | ワグ | ジョンソン |
7 | ワグ | ジョンソン |
最初の2行は重複しており、最後の3行も重複していることがわかります。
DogId
列は一意の値を保持しますが(テーブルの主キーであるため)、重複を比較するときにその列を無視します。主キーを含むテーブルの重複排除が必要になることがよくあるので、次の例を使用してそれを行うことができます。
上記の表を重複排除するための最初のオプションは次のとおりです。
DELETE FROM Dogs
WHERE DogId IN (
SELECT DogId FROM Dogs
MINUS SELECT MIN(DogId) FROM Dogs
GROUP BY FirstName, LastName
);
SELECT * FROM Dogs;
結果:
DOGID | FIRSTNAME | 姓 |
---|---|---|
1 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |
重複は削除されました(ただし、各重複の1行が残っています)。
または、 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 | 姓 |
---|---|---|
2 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
7 | ワグ | ジョンソン |
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 | 姓 |
---|---|---|
1 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |
別のオプションは次のとおりです:
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 | 姓 |
---|---|---|
1 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |
Oracleの各行にはrowid
があります 行のアドレスを返す疑似列。 rowid
はテーブル内の行の一意の識別子であり、通常、その値はデータベース内の行を一意に識別します(ただし、同じクラスターに一緒に格納されている異なるテーブル内の行は同じ 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 | 姓 |
---|---|---|
1 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |
この例は少し不必要に思えるかもしれませんが、すでに主キー列があることを考えると、 rowid
を使用したい場合があります。 。 rowid
何らかの理由で主キー列を使用できない場合、またはテーブルに主キーがない場合に役立ちます。また、Oracleのドキュメントには、 rowid
と記載されています。 値は、単一の行にアクセスするための最速の方法です。
これが他の例ですが、 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 | 姓 |
---|---|---|
1 | バーク | スミス |
3 | Woof | ジョーンズ |
4 | ラフ | ロビンソン |
5 | ワグ | ジョンソン |