次の例は、Oracleデータベーステーブルから重複する行を返します。
次のデータを含むテーブルがあるとします。
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行も重複しています。この場合、重複する行には、ID列を含むすべての列で重複する値が含まれます。
次のクエリを使用して、重複している行の数を確認できます。
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より大きい行は重複しています。
カウントの降順で並べ替えることができるため、重複が最も多い行が最初に表示されます。
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 COUNT(*) DESC;
結果:
PETID PETNAME PETTYPE Count 4 Bark Dog 3 1 Wag Dog 2
もう1つのオプションは、ROW_NUMBER()
を使用することです。 ウィンドウ関数:
SELECT
PetId,
PetName,
PetType,
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
PetId,
PetName,
PetType,
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つを返します。
テーブルに主キー列が含まれていない場合、Oracleの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
これが機能する方法は、Oracleデータベースの各行にrowid
があります。 行のアドレスを返す疑似列。 rowid
はテーブル内の行の一意の識別子であり、通常、その値はデータベース内の行を一意に識別します。ただし、同じクラスターに一緒に格納されている異なるテーブルの行は、同じrowid
を持つ可能性があることに注意してください。 。
上記の例の利点の1つは、SELECT *
を置き換えることができることです。 DELETE
を使用 テーブルの複製を解除するため。
そして最後に、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
前の例と同じ結果です。
前の例と同様に、SELECT *
を置き換えることができます DELETE
を使用 テーブルから重複する行を削除するため。