「MERGE」タグアーカイブ

サブクエリを使ったUPDATE文:別テーブルの値で更新する方法

■ 概要

SQLでデータを更新する際、別のテーブルの値を参照してUPDATEしたい場面は多くあります。
たとえば、マスタテーブルの最新情報でトランザクションテーブルを更新するケースなどです。

この記事では、Oracleデータベースを例に、サブクエリを使ったUPDATE文の書き方をわかりやすく解説します。


■ 基本構文

Oracleでサブクエリを用いたUPDATEを行う場合、基本的な構文は次の通りです。

ここで重要なのは、
SET句の中でサブクエリを使って値を取得し、
WHERE EXISTSで更新対象を限定する点です。


■ 実際の例:商品価格マスタをもとに在庫テーブルを更新

【例題】

  • PRODUCT_MASTER(商品マスタ)テーブル:

    • PRODUCT_ID

    • PRICE(最新の価格)

  • STOCK_INFO(在庫情報)テーブル:

    • PRODUCT_ID

    • PRICE(販売価格を更新したい)

【目的】

マスタの最新価格を在庫情報に反映する。

【SQL例】


■ ポイント解説

  1. サブクエリは1行1列を返す必要がある

    • サブクエリが複数行を返すと ORA-01427: single-row subquery returns more than one row エラーになります。

    • PRODUCT_IDなどの条件で一意に絞り込みましょう。

  2. WHERE EXISTSで更新対象を限定

    • EXISTSを使わない場合、サブクエリが該当しないレコードは NULL で更新される可能性があります。

    • 余計な更新を防ぐためにも、WHERE EXISTSを併用するのが安全です。

  3. パフォーマンス最適化のためにインデックスを確認

    • 結合条件に使う列(例:PRODUCT_ID)にはインデックスを付与すると高速化できます。


■ 別の書き方:MERGE文を使う方法

Oracleでは、サブクエリUPDATEの代わりにMERGE文を使っても同じことができます。

MERGE文は「更新または挿入」を同時に扱える構文で、
大量データ更新時にはこちらの方が効率的なこともあります。


■ まとめ

方法特徴
サブクエリを使ったUPDATEシンプルで分かりやすい。少量データ更新に最適。
MERGE文更新+挿入を同時に扱える。大量データ更新に向く。

■ この記事のポイント

  • Oracleでサブクエリを使ったUPDATEは「単一行サブクエリ+EXISTS」で安全に実装する

  • 一意性を保証できない場合は MERGE の利用を検討

  • インデックス設計で性能を最適化

SQL:MERGE文でINSERTとUPDATEを一度に行う効率的な方法

MERGE文とは?

SQLのMERGE文は、対象テーブルにデータが存在する場合はUPDATE、存在しない場合はINSERTを1回の処理でまとめて行える便利な構文です。
従来は「UPDATE → 該当しなければINSERT」といった2回の処理が必要でしたが、MERGEを使うことで1回のSQLで済むため、処理効率やパフォーマンスが向上します。

本記事ではOracleをベースに解説しつつ、他DBでの対応についても補足します。


MERGE文の基本構文(Oracleの場合)



実用例①:顧客マスタの更新 or 追加

ID=C001 が存在すれば更新
✅ 存在しなければ新規追加


処理の流れ(フロー図で理解)


応用例②:条件によってDELETEも行う(Oracle/SQL Server対応)

✅ ステータスがCANCELなら削除
✅ そうでなければ更新
✅ 該当なしならINSERT


MERGE文のメリット

項目従来方法MERGE文
SQL実行回数UPDATEとINSERTの2回1回
パフォーマンスやや低い高い
ロジックの明確さ分岐が必要条件分が整理されやすい
メンテナンス性低め高い

注意点

注意点内容
ロックの影響大量データの場合、テーブルロックが発生しやすい
複雑な条件WHEN句が増えると可読性が下がる
DB依存性MySQLは8.0.19以降、PostgreSQLはINSERT ... ON CONFLICTで代替

他DBでの補足

DBMERGE対応備考
Oracle対応本記事基準
SQL Server対応ほぼ同構文
MySQL8.0.19~対応REPLACE/INSERT ON DUPLICATEも可
PostgreSQL15~対応それ以前はINSERT ON CONFLICT

まとめ

✅ MERGE文はINSERTとUPDATEを1回の処理にまとめる強力なSQL構文
✅ DELETEも組み合わせれば高度なロジックも実現可能
✅ Oracle・SQL Serverでは標準的に使用される
✅ MySQL/PostgreSQLではバージョン確認が必要

「同じキーのデータを更新 or 追加したい」場面で積極的に使いましょう!