はじめに
PostgreSQLに「MERGE」というコマンドが存在することをつい先日知りました。
どうやら複数の操作(INSERT、UPDATE、DELETE)を一度に実行できる便利なコマンドらしいので、この機会に試してみたいと思います。
テーブルの作成
まず、MERGEを実行するためのテーブルを用意します。
今回は、ワインの在庫管理を例として挙げます。
wines テーブル作成
今あるワインのリストと、その在庫数を保存している
CREATE TABLE wines (
winename VARCHAR(255) PRIMARY KEY, -- ワイン名
stock INT -- 在庫数
);
wine_stock_changes テーブル作成
新しいワインの入荷や売れたワインの数を記録している
CREATE TABLE wine_stock_changes (
winename VARCHAR(255), -- ワイン名
stock_delta INT -- 在庫の増減数
);
初期データ投入
-- wines にデータを挿入
INSERT INTO wines (winename, stock)
VALUES ('Chardonnay', 10), ('Merlot', 5);
-- wine_stock_changes にデータを挿入
INSERT INTO wine_stock_changes (winename, stock_delta)
VALUES ('Chardonnay', 5), ('Merlot', -6), ('Cabernet', 10);
MERGE
MERGE文の基本的な構文は以下のようになります。MERGE文を使うことで、ターゲットテーブルに対して条件に基づいて行の挿入、更新、削除を一度のステートメントで行うことができます。
MERGE INTO target_table AS t
USING source_table AS s
ON <join_condition>
WHEN MATCHED THEN
<update_action>
WHEN NOT MATCHED THEN
<insert_action>;
具体例:ワイン在庫の管理
wine_stock_changesからのデータを基に、winesテーブルの在庫を更新します。
MERGE INTO wines w
USING wine_stock_changes s
ON s.winename = w.winename
WHEN NOT MATCHED AND s.stock_delta > 0 THEN
INSERT (winename, stock) VALUES(s.winename, s.stock_delta)
WHEN MATCHED AND w.stock + s.stock_delta > 0 THEN
UPDATE SET stock = w.stock + s.stock_delta
WHEN MATCHED THEN
DELETE;
新しいワインがwinesテーブルに存在しない場合...
- 新しい在庫変更情報(stock_delta)が0より大きい場合、新しいワインをwinesテーブルに追加する
新しいワインがwinesテーブルに存在する場合...
- 在庫変更情報(stock_Delta)を追加しても在庫数が0より大きい場合、在庫数を更新する
- 在庫変更後に在庫数が0以下になる場合、そのワインをwinesテーブルから削除する
実行結果
実行前 winesテーブル
実行後 winesテーブル
wine_stock_changesの情報が更新、追加、削除されていることを確認。
まとめ
MERGEコマンドを使うことで、複数のデータ操作を効率的に一つのSQLステートメントで実行できました。このコマンドを使って、複雑なデータ処理をより簡潔に実装してみましょう!
参考サイト