MERGE 源选项

MERGE 操作将目标表联接到以下数据源之一:

  • 另一个表

  • 视图

  • 子查询结果集

从表和视图数据合并

可以将一个表中的数据合并到另一个表中,如下所示:

MERGE INTO target‑table USING { source‑table | source‑view } join-condition
   matching‑clause[ matching‑clause ]

如果指定视图,则 Vertica 会将视图名称扩展到其封装的查询,并将结果集用作合并源数据。

例如,VMart 表 public.product_dimension 包含当前和停产的产品。可以将所有停产的产品移动到单独的表 public.product_dimension_discontinued 中,如下所示:

=> CREATE TABLE public.product_dimension_discontinued (
     product_key int,
     product_version int,
     sku_number char(32),
     category_description char(32),
     product_description varchar(128));

=> MERGE INTO product_dimension_discontinued tgt
     USING product_dimension src ON tgt.product_key = src.product_key
                                AND tgt.product_version = src.product_version
     WHEN NOT MATCHED AND src.discontinued_flag='1' THEN INSERT VALUES
       (src.product_key,
        src.product_version,
        src.sku_number,
        src.category_description,
        src.product_description);
 OUTPUT
--------
   1186
(1 row)

源表 product_dimension 使用 product_keyproduct_version 两列来标识唯一产品。MERGE 语句在这些列上联接源表和目标表,以便返回不匹配行的单个实例。WHEN NOT MATCHED 子句包含一个筛选器 (src.discontinued_flag='1'),它将结果集缩减为仅包含停产的产品。剩余的行将插入到目标表 product_dimension_discontinued

从子查询结果集合并

可以将子查询返回的结果集合并到表中,如下所示:

MERGE INTO target‑table USING (subquery) sq-alias join-condition
   matching‑clause[ matching‑clause ]

例如,VMart 表 public.product_dimension 定义如下(DDL 截断):

CREATE TABLE public.product_dimension
(
    product_key int NOT NULL,
    product_version int NOT NULL,
    product_description varchar(128),
    sku_number char(32),
    ...
)
ALTER TABLE public.product_dimension
    ADD CONSTRAINT C_PRIMARY PRIMARY KEY (product_key, product_version) DISABLED;

product_keyproduct_version 列构成表的主键。可以修改此表,使其包含连接这两列的值的单个列。此列可用于唯一标识每个产品,同时还保留 product_keyproduct_version 的原始值。

可以使用查询另外两列的 MERGE 语句填充新列:

=> ALTER TABLE public.product_dimension ADD COLUMN product_ID numeric(8,2);
ALTER TABLE

=> MERGE INTO product_dimension tgt
     USING (SELECT (product_key||'.0'||product_version)::numeric(8,2) AS pid, sku_number
     FROM product_dimension) src
     ON tgt.product_key||'.0'||product_version::numeric=src.pid
     WHEN MATCHED THEN UPDATE SET product_ID = src.pid;
 OUTPUT
--------
  60000
(1 row)

以下查询验证新列值是否对应于 product_keyproduct_version 中的值:

=> SELECT product_ID, product_key, product_version, product_description
   FROM product_dimension
   WHERE category_description = 'Medical'
     AND product_description ILIKE '%diabetes%'
     AND discontinued_flag = 1 ORDER BY product_ID;
 product_ID | product_key | product_version |           product_description
------------+-------------+-----------------+-----------------------------------------
    5836.02 |        5836 |               2 | Brand #17487 diabetes blood testing kit
   14320.02 |       14320 |               2 | Brand #43046 diabetes blood testing kit
   18881.01 |       18881 |               1 | Brand #56743 diabetes blood testing kit
(3 rows)