雪花中SQL MERGE语句的结构?

时间:2020-02-26 20:36:58

标签: sql merge snowflake-cloud-data-platform

根据雪花docs的merge语句,我认为以下查询将起作用:

MERGE INTO TEST_TABLE AS T 
USING
    (SELECT * FROM (VALUES ('name1', 56.0), ('name2', 29.0))) AS S (USERNAME, BALANCE)
ON T.USERNAME = S.USERNAME
WHEN NOT MATCHED THEN
    INSERT
        (USERNAME, BALANCE)
    VALUES
        (S.USERNAME, S.BALANCE)
WHEN MATCHED THEN
    UPDATE SET
        USERNAME = S.USERNAME, BALANCE = S.BALANCE;

但是我得到了错误

SQL compilation error: error line 4 at position 16
invalid identifier 'S.USERNAME'

我还尝试过使用这样的WITH语句对源数据进行别名

WITH S (USERNAME, BALANCE) AS (
    SELECT * FROM (VALUES ('name1', 56.0), ('name2', 29.0))
)
MERGE INTO TEST_TABLE AS T 
USING S
ON T.USERNAME = S.USERNAME
.
.
.

但这会产生不同的错误

SQL compilation error:
syntax error line 4 at position 0 unexpected 'MERGE'.

有人可以帮助我更好地理解文档和我做错了什么吗?

3 个答案:

答案 0 :(得分:0)

以下是我们在生产环境中运行的一些代码:

MERGE INTO ${db_name~}.${schema~}.AGGREGATION_WATERMARK dst
USING ${db_name~}.${schema~}.EVENT_WATERMARK src ON dst.unit_id = src.unit_id
WHEN NOT MATCHED THEN INSERT (unit_id, time) VALUES (src.unit_id, src.time)
WHEN MATCHED AND src.time < dst.time THEN UPDATE
    SET dst.time = src.time,
    dst._update_time_utc = TO_TIMESTAMP_NTZ(CURRENT_TIMESTAMP);

也许列命名不适用于MERGE,但是如果您从以下位置更改内部子选择:

SELECT * FROM (VALUES ('name1', 56.0), ('name2', 29.0))

以命名其中的列,例如:

SELECT temp.* FROM VALUES ('name1', 56.0), ('name2', 29.0) temp (USERNAME, BALANCE)

那么当您将其别名为S时,它应该工作吗?

SELECT * FROM (SELECT temp.* FROM VALUES ('name1', 56.0), ('name2', 29.0) temp (USERNAME, BALANCE)) S;

外部select *仅在此处显示其在MERGE USING的内容之外工作

答案 1 :(得分:0)

有一些细微的差别,但是我相信这应该可行。

 WITH S (USERNAME, BALANCE) AS (
     SELECT USERNAME, BALANCE 
     FROM (VALUES ('name1', 56.0), ('name2', 29.0)) AS S (USERNAME, BALANCE)
 )
 MERGE TEST_TABLE AS T 
 USING S
 ON T.USERNAME = S.USERNAME
 WHEN MATCHED THEN
 UPDATE
 SET T.USERNAME = S.USERNAME
    ,T.BALANCE = S.BALANCE
 WHEN NOT MATCHED BY TARGET THEN
 INSERT (USERNAME, BALANCE)
 VALUES (S.USERNAME, S.BALANCE);

答案 2 :(得分:0)

您已经发现,Snowflake错误地处理了表别名上的列别名

比较(因您的错误而失败)

SELECT o.one
FROM (SELECT 1) o(one);

with(成功运行)

SELECT o.one
FROM (SELECT 1 AS one) o;

我怀疑是否将SELECT *扩展到列的命名列表,并将AS S (USERNAME, BALANCE)更改为简单的AS S,则查询将编译。