重複する行があるかどうか(つまり、すべての列の値が等しいかどうか)を調べたいOracleテーブルがあります。問題は、行に一意の主キーがあるため、基本的にこれを妨げているため、それらを除外したいということです。
そのようなタスクを実行するときに(主キー列を除くすべての列を一覧表示する代わりに)主キーを無視して、重複する行を見つける方法はありますか?
重複する行があるかどうか(つまり、すべての列の値が等しいかどうか)を調べたいOracleテーブルがあります。問題は、行に一意の主キーがあるため、基本的にこれを妨げているため、それらを除外したいということです。
そのようなタスクを実行するときに(主キー列を除くすべての列を一覧表示する代わりに)主キーを無視して、重複する行を見つける方法はありますか?
GROUP BY
いいえ、句の主キー列を除くすべての列をリストするだけです:
CREATE TABLE mytable (
pk NUMBER PRIMARY KEY,
c1 NUMBER NOT NULL,
c2 NUMBER
);
INSERT INTO mytable (pk, c1, c2) VALUES (100, 1, 1);
INSERT INTO mytable (pk, c1, c2) VALUES (101, 1, 1);
INSERT INTO mytable (pk, c1, c2) VALUES (102, 2, 1);
INSERT INTO mytable (pk, c1, c2) VALUES (103, 2, null);
INSERT INTO mytable (pk, c1, c2) VALUES (104, 2, null);
SELECT c1, c2
FROM mytable
GROUP BY c1, c2
HAVING COUNT(*) > 1;
C1 C2
----- -----
1 1
2 (null)
非主キー列を見つけるには、次のクエリを使用できます。ほとんどのテーブルでは、クエリを貼り付けたり実行したりするよりも、列を入力する方が速くなります。
SELECT column_name
FROM user_tab_columns co
WHERE co.table_name = 'MYTABLE'
AND NOT EXISTS (
SELECT *
FROM user_constraints pk
JOIN user_cons_columns pc USING (owner, constraint_name)
WHERE pk.table_name = co.table_name
AND constraint_type='P'
AND co.column_name = pc.column_name)
ORDER BY co.column_id;
他の列を明示的にリストする必要があります。
場合によっては、動的 SQL を使用して必要なクエリを生成できます。しかし、これが 1 つのテーブルだけの場合は、あまり役に立ちません。数十または数百のテーブルを比較するプロセスを自動化しようとしている場合は、動的 SQL アプローチの方が管理しやすい可能性があります。