【问题标题】:Snowflake MERGE how to keep chronological orderSnowflake MERGE如何保持时间顺序
【发布时间】:2021-05-11 15:53:28
【问题描述】:

Snowflake 有一个非常有用的构造

MERGE INTO ...  WHEN MATCHED THEN UPDATE ...   WHEN NOT MATCHED THEN INSERT ...

一种非常常见的情况是,您只需要在传入的数据较新时进行更新,如果不是,则将其丢弃。 有没有办法在一条语句中做到这一点,或者我需要编写一个存储过程来读取现有行并在代码中决定是否合并传入的行。

【问题讨论】:

    标签: merge snowflake-cloud-data-platform


    【解决方案1】:

    您可以使用 AND 子句向 WHEN MATCHED 子句添加额外的逻辑:

    WHEN MATCHED [ AND <case_predicate> ] THEN ...
    

    【讨论】:

      【解决方案2】:

      假设我们要实现SCD 1 - overwrite,那么我们可以使用MERGE,例如:

      MERGE INTO tab trg
      USING src_tab src
        ON trg.business_key = src.business_key
      WHEN NOT MATCHED
          THEN INSERT(business_key, col1, col2) 
               VALUES (src.business_key, src.col1, src.col2) 
      WHEN MATCHED 
       -- if nothing has change for non-key attribute, do not update
       AND HASH(trg.col1,trg.col2) != HASH(src.col1,src.col2) 
           THEN UPDATE SET trg.col1 = src.col1
                          ,trg.col2 = src.col2
                          ,trg.sys_load_date = CURRENT_TIMESTAMP();
      

      示例场景:

      CREATE OR REPLACE TABLE tab(sys_key INT IDENTITY(1,1),
                                  business_key INT NOT NULL,
                                  col1 STRING,
                                  col2 STRING,
                                  sys_load_date DATETIME DEFAULT CURRENT_TIMESTAMP());
                                  
      CREATE OR REPLACE TABLE src_tab(business_key INT, col1 STRING, col2 STRING);
      

      示例运行:

      -- initial data                    
      INSERT OVERWRITE INTO src_tab VALUES (10, NULL, NULL), (20, 'a','a');
      --MERGE
      SELECT * FROM tab ORDER BY sys_key;
      /*
      SYS_KEY BUSINESS_KEY    COL1    COL2    SYS_LOAD_DATE
      1   10          2021-05-11 11:34:31.337
      2   20  a   a   2021-05-11 11:34:31.337
      */
      
      -- first row does not change, new row
      INSERT OVERWRITE INTO src_tab VALUES (10, NULL, NULL), (30, 'b','b');
      --MERGE
      SELECT * FROM tab ORDER BY sys_key;
      /*
      SYS_KEY BUSINESS_KEY    COL1    COL2    SYS_LOAD_DATE
      1   10          2021-05-11 11:34:31.337
      2   20  a   a   2021-05-11 11:34:31.337
      4   30  b   b   2021-05-11 11:34:47.298
      */
      
      -- change row 1
      INSERT OVERWRITE INTO src_tab VALUES (10, 'x', NULL);
      -- MERGE
      SELECT * FROM tab ORDER BY sys_key;
      /*
      SYS_KEY BUSINESS_KEY    COL1    COL2    SYS_LOAD_DATE
      1   10  x       2021-05-11 11:35:32.122
      2   20  a   a   2021-05-11 11:34:31.337
      4   30  b   b   2021-05-11 11:34:47.298
      */
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-17
        • 2012-06-22
        • 2016-11-01
        • 2014-09-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多