【Oracle】SELECT結果をもとにUPDATEする方法をわかりやすく解説!

スポンサーリンク

業務システムの運用やデータメンテナンスにおいて、「ある条件に合致したレコードだけを更新したい」といった場面は、決して珍しくございません。特に、他のテーブルから取得した情報をもとにデータを更新する必要がある場合、SELECTの結果を利用してUPDATEを行うという操作は、非常に重要なスキルの一つといえるでしょう。

本記事では、Oracleデータベースにおいて SELECTした結果を用いてデータをUPDATEする方法 について、丁寧に解説してまいります。基本的なUPDATE文の復習から始まり、サブクエリやMERGE文を用いた応用的な手法まで、実務に役立つ知識を段階的にご紹介いたします。

方法1:サブクエリを使ったUPDATE

単純な条件によるUPDATEだけではなく、別のテーブルの値や、計算結果をもとにレコードを更新したい、といったケースも現場ではよく見受けられます。

そのような場合に活用できるのが、サブクエリ(副問い合わせ)を用いたUPDATE文です。

例:部署ごとの平均給与に従業員の給与を更新する

以下のSQL文では、各従業員の所属部署ごとに平均給与を計算し、それをそのまま給与に反映しています。

UPDATE employees e
SET salary = (
    SELECT AVG(salary)
    FROM employees
    WHERE department_id = e.department_id
)
WHERE EXISTS (
    SELECT 1
    FROM departments d
    WHERE d.department_id = e.department_id
);

このUPDATE文のポイントは以下の通りです。

  • SET句の中にサブクエリを使い、同じ部署の平均給与を取得しています。これは相関サブクエリと呼ばれ、外側のテーブル(e.department_id)の値を参照できます。
  • WHERE EXISTSで、更新対象の部署がdepartmentsテーブルに存在するかどうかを確認しています。
    データの整合性を保つ目的で加えていますが、必須ではありません。

NULLや更新対象なしへの対策

サブクエリを使う際には、更新値がNULLになる可能性も考慮しておくと安心です。たとえば、該当部署の給与データがなければ、AVGはNULLを返すため、更新後の給与もNULLになってしまいます。

そのような場合は、NVL()関数を使って、NULLの代わりに元の値を維持する書き方もできます。

UPDATE employees e
SET salary = NVL((
    SELECT AVG(salary)
    FROM employees
    WHERE department_id = e.department_id
), e.salary);

これにより、サブクエリの結果がNULLでも、NULLで更新されずもとの給与がそのまま保持されます。

パフォーマンスの考慮

相関サブクエリは便利な一方で、行ごとにサブクエリを評価するため、対象レコードが多いと処理に時間がかかることがあります。
パフォーマンスが問題になる場合は、事前にビューや一時表を用意するなどの対策も有効です。

方法2:MERGE文を使った更新(上級者向け)

UPDATE処理の中でも、少し高度な方法として「MERGE文(マージ文)」があります。
これは、対象のテーブルと別のテーブルを突き合わせて、「一致すればUPDATE」「一致しなければINSERT」というような複合的な操作を、1つのSQL文で実行できる機能です。

この構文は、データの同期やマスターデータの取り込みといった業務で特に力を発揮します。

MERGE文の基本構文

MERGE文の基本構文を、source_tableの値をtarget_tableに反映させる例を使って解説します。

MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN MATCHED THEN
    UPDATE SET t.value = s.value;

ポイントは以下のとおりです。

  • MERGE INTO で更新対象のテーブルを指定
  • USING で突き合わせる元のテーブルを指定
  • ON でマッチ条件(結合条件)を定義
  • WHEN MATCHED THEN で更新内容を指定

このSQL文では、idが一致する行があった場合に、target_tableの値をsource_tableの値で更新します。

INSERTも一緒に処理することができる

MERGE文の大きな特徴は、「一致しなかった場合にはINSERTする」といった処理も組み込める点です。

MERGE INTO target_table t
USING source_table s
ON (t.id = s.id)
WHEN MATCHED THEN
    UPDATE SET t.value = s.value
WHEN NOT MATCHED THEN
    INSERT (id, value) VALUES (s.id, s.value);

このように書くことで、target_tableに存在しないレコードは新規に追加され、存在するレコードは更新されます。

注意点

MERGE文は非常に便利ですが、以下のような注意点もあります。

  • 複雑なロジックを含めると、SQLが長くなり保守性が下がることがあります。
  • トリガーや制約と組み合わせる場合、意図しない副作用が発生することがあるため、事前にテストをしておくと安心です。
  • 条件式が曖昧だと、意図しない複数更新が発生する可能性があるため、結合条件は慎重に設定しましょう。

まとめ

この記事では、OracleでSELECTした結果をもとにUPDATEする方法について、基本から応用まで段階的にご紹介しました。

ポイントを簡単に振り返ってみましょう。

  • 基本的なUPDATE文では、WHERE句で条件を指定して対象行を絞り込みます。
  • SELECTの結果をもとにUPDATEする方法として、サブクエリを用いた書き方が有効です。
  • より複雑な更新処理が必要な場合は、MERGE文を使うことで、条件に応じた更新や挿入処理を柔軟に行えます。
  • どの方法を使うにしても、事前にSELECTで対象データを確認し、意図しない更新を防ぐことが重要です。
  • 大量のデータを扱う際は、パフォーマンスやトランザクション管理にも注意しましょう。

UPDATE文は業務で頻繁に使う操作の一つですが、便利な分、扱い方によってはデータを壊してしまうリスクもあります。
確実な確認とテストを行いながら、正確で安全なSQLを書く習慣を身につけていきましょう!

Oracle
スポンサーリンク
なんくるをフォローする

コメント

タイトルとURLをコピーしました