Kar*_*lHC 7 snowflake-cloud-data-platform
我正在尝试创建一个执行 MERGE 语句的 Snowflake 任务。
\n但是,Snowflake 似乎无法识别 \xe2\x80\x9c(当与 target\xe2\x80\x9d 不匹配时)或 \xe2\x80\x9c(当与 source\xe2\x80\x9d 语句不匹配时)。
\ncreate or replace task MERGE_TEAM_TOUCHPOINT\n warehouse = COMPUTE_WH\n schedule = '1 minute'\n when system$stream_has_data('TEAMTOUCHPOINT_CDC')\nas\nmerge into dv.Team_Touchpoint as f using TeamTouchpoint_CDC as s\n on s.uniqueid = f.uniqueid\n when matched then \n update set TEAMUNIQUEID = s.TEAMUNIQUEID,\n TOUCHPOINTUNIQUEID = s.TOUCHPOINTUNIQUEID\n when not matched by target then \n insert (\n ID,\n UniqueID,\n TEAMUNIQUEID,\n TOUCHPOINTUNIQUEID \n )\n values (\n s.ID,\n s.UniqueID,\n s.TEAMUNIQUEID,\n s.TOUCHPOINTUNIQUEID\n )\n when not matched by source then delete;\nRun Code Online (Sandbox Code Playgroud)\n我怎样才能做到这一点?除了在 JavaScript 中创建一个存储过程来首先截断表,然后插入临时表中的所有内容之外,真的没有其他方法吗?
\n队友建议的解决方法:
MATCHED_BY_SOURCE基于全连接定义,然后查看a.col或b.col是否为null:merge into TARGET t
using (
select <COLUMN_LIST>,
iff(a.COL is null, 'NOT_MATCHED_BY_SOURCE', 'MATCHED_BY_SOURCE') SOURCE_MATCH,
iff(b.COL is null, 'NOT_MATCHED_BY_TARGET', 'MATCHED_BY_TARGET') TARGET_MATCH
from SOURCE a
full join TARGET b
on a.COL = b.COL
) s
on s.COL = t.COL
when matched and s.SOURCE_MATCH = 'NOT_MATCHED_BY_SOURCE' then
<DO_SOMETHING>
when matched and s.TARGET_MATCH = 'NOT_MATCHED_BY_TARGET' then
<DO_SOMETHING_ELSE>
;
Run Code Online (Sandbox Code Playgroud)
“按目标”和“按源”都不是 Snowflake 的 MERGE 命令中的有效关键字,并且匹配仅是“按目标”( https://docs.snowflake.com/en/sql-reference/sql/合并.html)。为了实现您的目标,您需要与合并分开运行删除 - 在合并中您将能够运行更新(当匹配时)和插入(当“按目标”不匹配时),因为实际上可以处理删除仅当“按目标”匹配时才进行合并。
您可以在存储过程中的单个显式事务中处理两个步骤(1.DELETE;2.MERGE-UPDATE&INSERT),或者通过两个单独的任务(其中之一是 AFTER 任务)处理两个不同的事务。
或者,您可以使用可选参数OVERWRITE运行 INSERT ,这将运行目标表的 TRUNCATE 并随后从源表加载,所有这些都在单个事务中进行: https ://docs.snowflake.com/en/sql-参考/sql/insert.html#可选参数
以下是 DELETE + MERGE(UPDATE&INSERT) 方法的可重现示例:
USE DEV;
CREATE OR REPLACE TEMPORARY TABLE Public.My_Merge_Target (
Id INTEGER, Name VARCHAR
)
AS
SELECT column1, column2
FROM (VALUES (1, 'Stay as is'), (2, 'This name has to change'), (3, 'This needs to go'));
CREATE OR REPLACE TEMPORARY TABLE Public.My_Merge_Source (
Id INTEGER, Name VARCHAR
)
AS
SELECT column1, column2
FROM (VALUES (1, 'Stay as is'), (2, 'This is the new name for id=2'), (4, 'A new row'));
SELECT * FROM Public.My_Merge_Target ORDER BY Id;
/*
------------------------------------
Id | Name
------------------------------------
1 | Stay as is
2 | This name has to change
3 | This needs to go
*/
SELECT * FROM Public.My_Merge_Source ORDER BY Id;
/*
------------------------------------
Id | Name
------------------------------------
1 | Stay as is
2 | This is the new name for id=2
4 | A new row
*/
DELETE FROM Public.My_Merge_Target AS trg
USING (
SELECT t.Id FROM Public.My_Merge_Source AS s
RIGHT JOIN Public.My_Merge_Target AS t
ON s.Id = t.Id
WHERE s.Id IS NULL
) AS src
WHERE trg.Id = src.Id;
/*
-----------------------
number of rows deleted
-----------------------
1
-----------------------
*/
SELECT * FROM Public.My_Merge_Target ORDER BY Id;
/*
------------------------------------
Id | Name
------------------------------------
1 | Stay as is
2 | This is the new name
*/
MERGE
INTO Public.My_Merge_Target AS trg
USING (
SELECT Id, Name
FROM Public.My_Merge_Source
) AS src
ON
trg.Id = src.Id
WHEN
MATCHED
AND (src.Name != trg.Name) THEN UPDATE
SET Name = src.Name
WHEN
NOT MATCHED THEN INSERT (Id, Name)
VALUES (src.Id, src.Name)
;
/*
-------------------------------------------------
number of rows inserted | number of rows updated
-------------------------------------------------
1 | 1
-------------------------------------------------
*/
SELECT * FROM Public.My_Merge_Target ORDER BY Id;
/*
------------------------------------
Id | Name
------------------------------------
1 | Stay as is
2 | This is the new name for id=2
4 | A new row
*/
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4864 次 |
| 最近记录: |