可用版本: Dev (3.21) | 最新 (3.20) | 3.19 | 3.18 | 3.17 | 3.16 | 3.15 | 3.14 | 3.13 | 3.12 | 3.11

MERGE语句

适用于 ✅ 开源版   ✅ 专业版   ✅ 企业版

MERGE 语句是最先进的标准 SQL 功能之一。 虽然它可以用于 UPSERT 语义(类似于 INSERT .. ON DUPLICATE KEY UPDATEINSERT .. ON CONFLICT),但它的功能远不止这些。

标准 MERGE 语句的目的是获取一个 TARGET 表,并将来自 SOURCE 表的数据合并(INSERTUPDATEDELETE)到其中。

这是一个示例,假设我们有一个 BOOK_TO_BOOK_STORE_STAGING 表,我们在进行 ETL 时使用它将数据加载到“实际”的 BOOK_TO_BOOK_STORE 数据表中

-- Merge staging data into the real table
MERGE INTO BOOK_TO_BOOK_STORE
USING (
  SELECT * FROM BOOK_TO_BOOK_STORE_STAGING
)
ON BOOK_TO_BOOK_STORE.BOOK_ID
   = BOOK_TO_BOOK_STORE_STAGING.BOOK_ID
AND BOOK_TO_BOOK_STORE.NAME
   = BOOK_TO_BOOK_STORE_STAGING.NAME
WHEN MATCHED THEN UPDATE
  SET STOCK = BOOK_TO_BOOK_STORE_STAGING.STOCK
WHEN NOT MATCHED THEN INSERT (
  BOOK_ID,
  NAME,
  STOCK
)
VALUES (
  BOOK_TO_BOOK_STORE_STAGING.BOOK_ID,
  BOOK_TO_BOOK_STORE_STAGING.NAME,
  BOOK_TO_BOOK_STORE_STAGING.STOCK
);
create.mergeInto(BOOK_TO_BOOK_STORE)
      .using(BOOK_TO_BOOK_STORE_STAGING)
      .on(BOOK_TO_BOOK_STORE.BOOK_ID
          .eq(BOOK_TO_BOOK_STORE_STAGING.BOOK_ID)
      .and(BOOK_TO_BOOK_STORE.NAME
          .eq(BOOK_TO_BOOK_STORE_STAGING.NAME)))
      .whenMatchedThenUpdate().set(
          BOOK_TO_BOOK_STORE.STOCK,
          BOOK_TO_BOOK_STORE_STAGING.STOCK
      )
      .whenNotMatchedThenInsert(
           BOOK_TO_BOOK_STORE.BOOK_ID,
           BOOK_TO_BOOK_STORE.NAME,
           BOOK_TO_BOOK_STORE.STOCK
      )
      .values(
           BOOK_TO_BOOK_STORE_STAGING.BOOK_ID,
           BOOK_TO_BOOK_STORE_STAGING.NAME,
           BOOK_TO_BOOK_STORE_STAGING.STOCK
       )
      .execute();

MERGE 语句视为 TARGETSOURCE 表之间的 RIGHT JOIN,其中 ON 子句定义了 TARGETSOURCE 行之间是否存在 MATCH

  • 如果存在 MATCH,则可以对 TARGET 行执行 UPDATEDELETE 操作
  • 如果没有 MATCH,则 SOURCE 行可用于对 TARGET 表执行 INSERT 操作
  • 如果没有 MATCH,某些方言还支持 BY SOURCE 子句,以指定应执行 LEFT JOIN 或 FULL JOIN,以便允许对 TARGET 表中没有匹配行的现有行执行 UPDATEDELETE 操作。

以下各节详细解释了 MERGE 语句。

反馈

您对此页面有任何反馈吗? 我们很乐意听到您的反馈!

The jOOQ Logo