SQL 指南書集 目次 - ray88’s diary
【お題】
以下のテーブルより重複行を削除する
【下準備】
--下準備:テーブルにシリアルナンバーの列を追加する ALTER TABLE Products2 ADD COLUMN id SERIAL PRIMARY KEY;
【重複行削除のSQL①】
各重複グループから最大のidを持つ行のみ残し、その他は削除する
※WHERE id < (SELECT MAX(P2.id)...)の条件は、
P1のidがそのグループの最大idよりも小さい場合にTRUEとなる。
つまり、各重複グループの中で最大のidを持つ行以外の行が削除対象となります。
--重複行を削除するSQL その1:極値関数「MAX」を利用 DELETE FROM Products2 P1 WHERE id < (SELECT MAX(P2.id) FROM Products2 P2 WHERE P1.name = P2.name AND P1.price = P2.price);
【重複行削除のSQL②】
※EXISTSは、内側のサブクエリが1行以上の結果を返す場合にTRUEとなる。
この場合、それはP1と同じnameとpriceを持ち、かつP2のidがP1のidより大きい行が存在することを
意味する。これにより、各重複グループの中で最大のidを持つ行以外の行が削除対象となります。
--重複行を削除するSQL その2:非等値結合 「<」,「>」 を利用 DELETE FROM Products2 P1 WHERE EXISTS (SELECT * FROM Products2 P2 WHERE P1.name = P2.name AND P1.price = P2.price AND P1.id < P2.id);
【参考】テーブル作成用SQL
※シリアル番号なしのテーブル
CREATE TABLE Products2 (name VARCHAR(16),price INTEGER NOT NULL); INSERT INTO Products2 VALUES('りんご', 50); INSERT INTO Products2 VALUES('みかん', 100); INSERT INTO Products2 VALUES('みかん', 100); INSERT INTO Products2 VALUES('みかん', 100); INSERT INTO Products2 VALUES('バナナ', 80);
※最初からシリアルナンバー付きのテーブルを作成する場合はこちら
CREATE TABLE Products2 ( id SERIAL, name VARCHAR(16), price INTEGER NOT NULL ); INSERT INTO Products2(name, price) VALUES('りんご', 50); INSERT INTO Products2(name, price) VALUES('みかん', 100); INSERT INTO Products2(name, price) VALUES('みかん', 100); INSERT INTO Products2(name, price) VALUES('みかん', 100); INSERT INTO Products2(name, price) VALUES('バナナ', 80);