こちらを参考にしました。
PostgreSQL 16 INSERT
元のテーブルの状態
city=# select * from cities;
id | name | population | date_mod
-------+--------+------------+------------
t3461 | 広島 | 25176 | 2003-09-24
t3462 | 福山 | 47935 | 2003-05-15
t3463 | 東広島 | 28654 | 2003-02-08
(3 rows)
最初の Upsert
データが挿入されます。
upsert01.sql
INSERT INTO cities (id,name,population,date_mod)
VALUES ('t3501','山口',23541,'2022-5-10'),
('t3502','下関',83762,'2022-5-10'),
('t3503','宇部',31725,'2022-5-10')
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name,
population = EXCLUDED.population,
date_mod = EXCLUDED.date_mod;
実行結果
city=# select * from cities order by id;
id | name | population | date_mod
-------+--------+------------+------------
t3461 | 広島 | 25176 | 2003-09-24
t3462 | 福山 | 47935 | 2003-05-15
t3463 | 東広島 | 28654 | 2003-02-08
t3501 | 山口 | 23541 | 2022-05-10
t3502 | 下関 | 83762 | 2022-05-10
t3503 | 宇部 | 31725 | 2022-05-10
(6 rows)
次の Upsert
データが更新されます。
upsert02.sql
INSERT INTO cities (id,name,population,date_mod)
VALUES ('t3501','山口',993541,'2024-7-12'),
('t3502','下関',993762,'2024-7-12'),
('t3503','宇部',981725,'2024-7-12')
ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name,
population = EXCLUDED.population,
date_mod = EXCLUDED.date_mod;
実行結果
city=# select * from cities;
id | name | population | date_mod
-------+--------+------------+------------
t3461 | 広島 | 25176 | 2003-09-24
t3462 | 福山 | 47935 | 2003-05-15
t3463 | 東広島 | 28654 | 2003-02-08
t3501 | 山口 | 993541 | 2024-07-12
t3502 | 下関 | 993762 | 2024-07-12
t3503 | 宇部 | 981725 | 2024-07-12
(6 rows)