【问题标题】:Snowflake merge using same table雪花合并使用同一张表
【发布时间】:2021-06-26 11:03:47
【问题描述】:

我有一张表,它的主键是 1,另一列是卷号。

我想检查表中是否存在 id 值,如果是则更新其卷号。如果没有,则在表中插入 id 和卷号。

我正在尝试使用合并。

parameters: id_value, roll_number


merge into "test_table"  as t
using (SELECT * from "test_table" where id = id_value) as s
on t.id=s.id
when matched then
    update set t.roll_number=5
when not matched then
    insert (id, roll_number) values (id_value,roll_number);

当值存在时它会更新表,但在插入的情况下不起作用。没有插入任何行。

【问题讨论】:

    标签: snowflake-cloud-data-platform snowflake-schema


    【解决方案1】:

    您应该能够使用如下所示的合并语句来执行此操作:

    -- Set params first
    set (id_value, roll_number) = (1, 5);
    
    -- Run merge
    merge into test_table
        using (select
                   column1 as id,
                   column2 as roll_number
               from
               values ($id_value, $roll_number)) tt
        on test_table.id = tt.id
        when matched then update set test_table.roll_number = tt.roll_number
        when not matched then insert (id, roll_number) values (tt.id, tt.roll_number);
    

    完整示例:

    -- Set up example table and insert values
    create temporary table test_table
    (
        id          number,
        roll_number number
    );
    
    -- Insert some sample data
    insert overwrite into test_table
    values (1, 2),
           (2, 1),
           (3, 6);
    
    -- Here is what the initial table looks like
    select *
    from test_table;
    -- +--+-----------+
    -- |ID|ROLL_NUMBER|
    -- +--+-----------+
    -- |1 |2          |
    -- |2 |1          |
    -- |3 |6          |
    -- +--+-----------+
    
    -- Set the parameters
    set (id_value, roll_number) = (1, 5);
    
    -- Run the merge statement using the parameters.
    -- This should update the roll_number with ID of 1 to value 5.
    merge into test_table
        using (select
                   column1 as id,
                   column2 as roll_number
               from
               values ($id_value, $roll_number)) tt
        on test_table.id = tt.id
        when matched then update set test_table.roll_number = tt.roll_number
        when not matched then insert (id, roll_number) values (tt.id, tt.roll_number);
    
    -- Check what the table looks like now
    select *
    from test_table;
    -- +--+-----------+
    -- |ID|ROLL_NUMBER|
    -- +--+-----------+
    -- |1 |5          | <---- Updated row
    -- |2 |1          |
    -- |3 |6          |
    -- +--+-----------+
    
    -- Set the parameters to an id that doesn't exist in the table.
    set (id_value, roll_number) = (4, 3);
    
    -- Now the same merge statement should insert
    -- a new record with ID 4 and roll_number 3.
    merge into test_table
        using (select
                   column1 as id,
                   column2 as roll_number
               from
               values ($id_value, $roll_number)) tt
        on test_table.id = tt.id
        when matched then update set test_table.roll_number = tt.roll_number
        when not matched then insert (id, roll_number) values (tt.id, tt.roll_number);
    
    -- Check what the table looks like now
    select *
    from test_table;
    -- +--+-----------+
    -- |ID|ROLL_NUMBER|
    -- +--+-----------+
    -- |4 |3          | <---- New row
    -- |1 |5          |
    -- |2 |1          |
    -- |3 |6          |
    -- +--+-----------+
    

    【讨论】:

      【解决方案2】:

      当源和目标是同一个表时,如果它不存在于目标中,它就不会在源中。所以没有什么可插入的。

      【讨论】:

      • 那么如果是运行更新命令或不运行插入命令,那么选择和检查数据是否存在的最佳方法是什么?有没有更好或更有效的方法来做同样的事情?
      猜你喜欢
      • 2019-04-05
      • 2022-06-19
      • 2021-08-30
      • 1970-01-01
      • 2013-09-07
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 1970-01-01
      相关资源
      最近更新 更多