■ はじめに
https://dk521123.hatenablog.com/entry/2023/01/16/000000
https://dk521123.hatenablog.com/entry/2024/09/12/003814
で、SQLの集合演算について、扱った。 今回は、SQLの集合演算を利用して、 delete + insert 後のデータ確認してみる。
目次
【1】データ準備 1)使用データ 2)データ登録 【2】データ確認 1)新規データを抽出する 2)更新データを抽出する 3)既存データを抽出する
【1】データ準備
* 試すDBがなければ、以下のサイトで行うといいかも、、、
SQL Fiddle
https://www.db-fiddle.com/
1)使用データ
* PostgreSQL15を想定
データ定義
CREATE TABLE member_20240914 ( id INT, name VARCHAR(50), gender VARCHAR(1), country_code VARCHAR(3), class VARCHAR(10), updated_date DATE ); CREATE TABLE member_20240915 ( id INT, name VARCHAR(50), gender VARCHAR(1), country_code VARCHAR(3), class VARCHAR(10), updated_date DATE );
使用データ
-- INSERT member_20240914 INSERT INTO member_20240914 (id,name,gender,country_code,class,updated_date) VALUES (1,'Mike','m','USA','bronze','2024-09-14'), (2,'Tom',NULL,'GBR','gold','2024-09-14'), (3,'Smith','f',NULL,'silver','2024-09-14'), (4,'Ken',NULL,'JPN','gold','2024-09-14'), (5,'Jack','m','UKR','gold','2024-09-14'), (6,'Henry','m','AUS','bronze','2024-09-14'), (7,'Sophia','f','JPN','platinum','2024-09-14'), (8,'George','m','USA',NULL,'2024-09-14'), (9,'Lily','f','JPN','bronze','2024-09-14'), (10,'Daisy','f','USA','platinum','2024-09-14') ; -- INSERT member_20240915 INSERT INTO member_20240915 (id,name,gender,country_code,class,updated_date) VALUES (2,'Tom','m','GBR','platinum','2024-09-15'), -- ☆更新1 (4,'Ken','m','JPN','gold','2024-09-15'), -- ☆更新2 (6,'Henry','m','AUS','silver','2024-09-15'), -- ☆更新3 (8,'George','m','USA','silver','2024-09-15'), -- ☆更新4 (11,'Leo','m',NULL,NULL,'2024-09-15'), -- ★新規1 (12,'Sam',NULL,'AUS','bronze','2024-09-15'), -- ★新規2 (13,'Olivia',NULL,'NZL','silver','2024-09-15'), -- ★新規3 (14,'John',NULL,'USA','silver','2024-09-15'), -- ★新規4 (15,'Naomi','f','JPN','bronze','2024-09-15'), -- ★新規5 (16,'Clara','f','USA','gold','2024-09-15') -- ★新規6 ;
2)データ登録
[1] 初回データ登録
-- 初回登録 CREATE TABLE member AS SELECT * FROM member_20240914; -- データ確認 SELECT * FROM member ORDER BY id;
id | name | gender | country_code | class | updated_date |
---|---|---|---|---|---|
1 | Mike | m | USA | bronze | 2024-09-14 |
2 | Tom | GBR | gold | 2024-09-14 | |
3 | Smith | f | silver | 2024-09-14 | |
4 | Ken | JPN | gold | 2024-09-14 | |
5 | Jack | m | UKR | gold | 2024-09-14 |
6 | Henry | m | AUS | bronze | 2024-09-14 |
7 | Sophia | f | JPN | platinum | 2024-09-14 |
8 | George | m | USA | 2024-09-14 | |
9 | Lily | f | JPN | bronze | 2024-09-14 |
10 | Daisy | f | USA | platinum | 2024-09-14 |
[2] 二回目登録 (delete + insert)
-- 2-0) 実行前にバックアップ(今回の場合、member_20240914と同じだが) CREATE TABLE member_previous AS SELECT * FROM member; -- 2-1) delete DELETE FROM member WHERE id IN (SELECT id FROM member_20240915); -- 2-2) INSERT INSERT INTO member (id,name,gender,country_code,class,updated_date) SELECT id,name,gender,country_code,class,updated_date FROM member_20240915; -- データ確認 SELECT * FROM member ORDER BY id;
現在のテーブル
id | name | gender | country_code | class | updated_date |
---|---|---|---|---|---|
1 | Mike | m | USA | bronze | 2024-09-14T00:00:00.000Z |
2 | Tom | m | GBR | platinum | 2024-09-15T00:00:00.000Z |
3 | Smith | f | silver | 2024-09-14T00:00:00.000Z | |
4 | Ken | m | JPN | gold | 2024-09-15T00:00:00.000Z |
5 | Jack | m | UKR | gold | 2024-09-14T00:00:00.000Z |
6 | Henry | m | AUS | silver | 2024-09-15T00:00:00.000Z |
7 | Sophia | f | JPN | platinum | 2024-09-14T00:00:00.000Z |
8 | George | m | USA | silver | 2024-09-15T00:00:00.000Z |
9 | Lily | f | JPN | bronze | 2024-09-14T00:00:00.000Z |
10 | Daisy | f | USA | platinum | 2024-09-14T00:00:00.000Z |
11 | Leo | m | 2024-09-15T00:00:00.000Z | ||
12 | Sam | AUS | bronze | 2024-09-15T00:00:00.000Z | |
13 | Olivia | NZL | silver | 2024-09-15T00:00:00.000Z | |
14 | John | USA | silver | 2024-09-15T00:00:00.000Z | |
15 | Naomi | f | JPN | bronze | 2024-09-15T00:00:00.000Z |
16 | Clara | f | USA | gold | 2024-09-15T00:00:00.000Z |
【2】データ確認
ここからが、本題、、、 delete + insert の場合でのデータ投入時で、 以下に分類できたとする (a) 新規データ (b) 更新データ (c) 既存データ(変わらずに残っているデータ) このデータを集合演算を使って抽出してみる
データ投入回数 | 投入データ日付 | 総カウント | (a)新規データ数 | (b)更新データ数 | (c)既存データ数 | 備考 |
---|---|---|---|---|---|---|
1回目投入時 | 2024-09-14 | 10 | - | - | - | |
2回目投入時 | 2024-09-15 | 16 | 6 | 4 | 5 | 更新データは偶数ID(#2~8)のもの |
1)新規データを抽出する
サンプル
-- 方法1:現在のテーブルから過去のテーブルでの差集合 SELECT id FROM member EXCEPT SELECT id FROM member_previous ORDER BY id ; -- [実行後のテーブルを使わない場合] -- => 入力したデータ と前テーブル がUniq key不一致したデータを出力する SELECT * FROM member_20240915 AS m0915 WHERE m0915.id NOT IN (SELECT id FROM member_previous) ORDER BY m0915.id;
id |
---|
11 |
12 |
13 |
14 |
15 |
16 |
[実行後のテーブルを使わない場合]
id | name | gender | country_code | class | updated_date |
---|---|---|---|---|---|
11 | Leo | m | 2024-09-15 | ||
12 | Sam | AUS | bronze | 2024-09-15 | |
13 | Olivia | NZL | silver | 2024-09-15 | |
14 | John | USA | silver | 2024-09-15 | |
15 | Naomi | f | JPN | bronze | 2024-09-15 |
16 | Clara | f | USA | gold | 2024-09-15 |
2)更新データを抽出する
サンプル
-- 方法1:実行前のテーブルから現在のテーブルで差集合する SELECT updated.id FROM( -- ★実行前のテーブルから現在のテーブルで差集合する SELECT id,name,gender,country_code,class,updated_date FROM member_previous AS old EXCEPT SELECT id,name,gender,country_code,class,updated_date FROM member AS m ) AS updated ORDER BY updated.id; -- [実行後のテーブルを使わない場合] -- => 前テーブル と 入力したデータ でUniq key一致したデータを出力する SELECT * FROM member_previous AS mp WHERE mp.id IN (SELECT id FROM member_20240915) ORDER BY mp.id;
id |
---|
2 |
4 |
6 |
8 |
[実行後のテーブルを使わない場合]
id | name | gender | country_code | class | updated_date |
---|---|---|---|---|---|
2 | Tom | GBR | gold | 2024-09-14 | |
4 | Ken | JPN | gold | 2024-09-14 | |
6 | Henry | m | AUS | bronze | 2024-09-14 |
8 | George | m | USA | 2024-09-14 |
3)既存データを抽出する
サンプル
-- 方法1:現在のテーブルから実行前のテーブルの全項目の共通部分(積集合)をする SELECT id,name,gender,country_code,class,updated_date FROM member AS m INTERSECT SELECT id,name,gender,country_code,class,updated_date FROM member_previous AS old ORDER BY id; -- [実行後のテーブルを使わない場合] -- => 前テーブル と 入力したデータ でUniq key不一致したデータを出力する -- => 結果は同じなので省略 SELECT * FROM member_previous AS mp WHERE mp.id NOT IN (SELECT id FROM member_20240915) ORDER BY mp.id;
id | name | gender | country_code | class | updated_date |
---|---|---|---|---|---|
1 | Mike | m | USA | bronze | 2024-09-14T00:00:00.000Z |
3 | Smith | f | silver | 2024-09-14T00:00:00.000Z | |
5 | Jack | m | UKR | gold | 2024-09-14T00:00:00.000Z |
7 | Sophia | f | JPN | platinum | 2024-09-14T00:00:00.000Z |
9 | Lily | f | JPN | bronze | 2024-09-14T00:00:00.000Z |
10 | Daisy | f | USA | platinum | 2024-09-14T00:00:00.000Z |
関連記事
SQL ~ 関係演算 / 集合論 ~
https://dk521123.hatenablog.com/entry/2023/01/16/000000
Snowflake ~ 関係演算 / 集合論 ~
https://dk521123.hatenablog.com/entry/2024/09/12/003814
SQL ~ テーブル差分を調査することを考える ~
https://dk521123.hatenablog.com/entry/2024/09/22/220455