MySQL

MySQLでUPSERT/MERGE(マージ)を行うSQL

Buy Me A CoffeeBuy Me a Coffee at ko-fi.com

Abstract

2つのテーブルで、本テーブルと差分更新データテーブルがあって、マージしたいことがよくあります。MySQLでこの時に使うUPSERT/MERGE(マージ)を行うSQLを紹介します。

今回は、以下の想定でSQLを作成します。

テーブル名説明
OS元のテーブル
OS_MODIFYING差分保持テーブル

上記のテーブルでOSテーブルとOS_MODIFYINGテーブルを比較し、OSテーブルにレコードがなければINSERT、レコードがあればUPDATEを行います。

達人に学ぶDB設計徹底指南書 初級者で終わりたくないあなたへ [ ミック ]

OSテーブル(元テーブル)

以下のDDLでテーブルを作成しデータをINSERTします。

CREATE TABLE OS(
    OS_VERSION VARCHAR(50),
    OS_NAME VARCHAR(50),
    DEV_CODE VARCHAR(50),
    ANNOUNCEMENT_DATE DATE,
    RELEASE_DATE DATE,
    PRIMARY KEY(OS_VERSION)
);
OS_VERSIONOS_NAMEDEV_CODEANNOUNCEMENT_DATERELEASE_DATE
Classic Mac OS System 1NULLNULLNULL1984-01-24
Mac OS X v10.0NULLCheetah2001-01-122001-03-24
macOS v10.12SierraNULL2016-06-132016-09-20
macOS v11Big SurNULL2020-06-222020-11-13
macOS v12NULLNULLNULLNULL
OS X v10.8Mountain LionZinfandel2012-02-162012-07-25
Rhapsody Developer ReleaseWindows TroubleME1111-11-111234-12-12

OS_MODIFYING(差分データテーブル)

OSテーブルと同じDDLでテーブルを作成。OS VERSIONが「1.0」をINSERTし「Rhapsody Developer Release」のレコードをUPDATEするようなデータを準備します。

CREATE TABLE OS_MODIFYING(
    OS_VERSION VARCHAR(50),
    OS_NAME VARCHAR(50),
    DEV_CODE VARCHAR(50),
    ANNOUNCEMENT_DATE DATE,
    RELEASE_DATE DATE,
    PRIMARY KEY(OS_VERSION)
);
OS_VERSIONOS_NAMEDEV_CODEANNOUNCEMENT_DATERELEASE_DATE
1.0Windows 1.0NULLNULL1985-11-20
Rhapsody Developer ReleaseNULLGrail1Z4 / Titan1UNULL1997-08-31

UPSERT(マージ)SQL

OSレコードに対して、OS_MODIFYINGの「1.0」のレコードをINSERTし「Rhapsody Developer Release」をUPDATEします

INSERT INTO OS
WITH mdfy AS (SELECT * FROM OS_MODIFYING b WHERE b.RELEASE_DATE IS NOT NULL)
SELECT * FROM (SELECT * FROM mdfy) a
ON DUPLICATE KEY UPDATE
OS_VERSION = a.OS_VERSION,
OS_NAME = a.OS_NAME,
DEV_CODE = a.DEV_CODE,
ANNOUNCEMENT_DATE = a.ANNOUNCEMENT_DATE,
RELEASE_DATE = a.RELEASE_DATE;

UPSERT(マージ)SQL実行結果

実行結果は以下の通り。

OS_VERSIONOS_NAMEDEV_CODEANNOUNCEMENT_DATERELEASE_DATE
1.0Windows 1.0NULLNULL1985-11-20
Classic Mac OS System 1NULLNULLNULL1984-01-24
Mac OS X v10.0NULLCheetah2001-01-122001-03-24
macOS v10.12SierraNULL2016-06-132016-09-20
macOS v11Big SurNULL2020-06-222020-11-13
macOS v12NULLNULLNULLNULL
OS X v10.8Mountain LionZinfandel2012-02-162012-07-25
Rhapsody Developer ReleaseNULLGrail1Z4 / Titan1UNULL1997-08-31

OS VERSIONの「1.0」のレコードが追加されており、「Rhapsody Developer Release」が更新することができました。