【SQL】条件によって処理を分けたいときMERGE INTOが便利【SQL Server】

  • 2020.07.20
  • SQL
【SQL】条件によって処理を分けたいときMERGE INTOが便利【SQL Server】

はじめに

コジマです。

今回はSQLのMERGE INTOの話をしようかと思います。

データの移行でワークテーブルから実テーブルにデータを移すときに
主キーが存在してたらUPDATEしたいし、存在してなかったらINSERTしたい!

なんて時に使います。

MVCでアプリ作ってるときにはあまりお目にかかりませんが、
外部システムと連携したシステムの運用が必要な時に使ったりします。

動作確認はSQL Serverだけで行っているので、その他のRDBだと使えるかもしれないし使えないかもしれません。

基本的な使い方

基本文法は以下の通りです。

MERGE INTO 登録先
USING 登録元
ON 結合条件
WHEN MATCHED THEN 存在するときの処理
WHEN NOT MATCHED THEN 存在しないときの処理

例えば、ユーザー情報を更新したいとき、こんな感じで書きます。

-- usersテーブルを更新したい
MERGE INTO users AS u
-- work_usersテーブルから更新したい
USING work_users AS wu
-- 結合条件はユーザーID
ON u.user_id = wu.user_id
-- usersテーブルに存在するユーザーIDだったら更新を行う
WHEN MATCHED THEN
  UPDATE SET
    u.user_id = wu.user_id,
    u.name = wu.name
    u.address = wu.address
    u.email = wu.email
-- usersテーブルに存在しないユーザーIDだったら登録を行う
WHEN NOT MATCHED THEN
  INSERT (
    u.user_id,
    u.name,
    u.address,
    u.email
  )
  VALUES (
    wu.user_id,
    wu.name,
    wu.address,
    wu.email
  )

MERGE INTOの注意点

とても便利なコマンドではありますが、注意すべき点が2点あります。

1:登録元と登録先のカラム構成が同じである必要がある

よくよく当たり前なんですけどね。
もし、カラム構成が違うもの動詞を扱う場合は副問合せ文を駆使してカラム構成を合わせてあげましょう。

2:登録先の同一レコードに対し複数回UPDATEまたはDELETEすることができない

例えば、usersテーブルのuser_id:1の田中さんに対し、
work_usersテーブルのuser_id:1の佐藤さんとuser_id:1の鈴木さんがいる場合は
どちらも田中さんに対してUPDATEしに行こうとしてしまいます。
このような場合、MERGE INTOはエラーとなってしまいます。

そうならないように結合条件はしっかり吟味する必要があります。

さいごに

SQLも突き詰めると便利なコマンドいっぱいあるし、とても奥深いですね。

公式のドキュメントは以下になります。
https://docs.microsoft.com/ja-jp/sql/t-sql/statements/merge-transact-sql?view=sql-server-ver15

この記事を面白いまたは役に立ったと思ってくれた方は是非私のTwitter(@kojimanotech)を
フォローしてくれたらうれしいです!

以上、コジマでした。


SQLカテゴリの最新記事