【发布时间】:2020-03-22 16:01:18
【问题描述】:
我正在尝试在 Google BigQuery(ETL 流程的一部分)中编写合并查询。
我有 Source (staging) 和 Target 表,我有 2 种合并数据的方法:经典的“Upsert”合并或插入新行(如果不匹配)列。
这是第一种方式(经典的“Upsert”)查询的示例:
MERGE DS.Target T
USING DS.Source S
ON T.Key=S.Key
WHEN NOT MATCHED THEN
INSERT ROW
WHEN MATCHED THEN
UPDATE SET Col1 = S.Col1, Col2 = S.Col2
这样,如果键存在,即使值相同,它也会始终更新 cols 的值。这也仅在密钥不可为空时才有效。
另一种方法是在值不匹配时插入新行:
MERGE DS.Target T
USING DS.Source S
ON T.A = S.A and T.B = S.B and T.C = S.C
WHEN NOT MATCHED THEN
INSERT ROW
我更喜欢这种方式,但是我发现当列类型为 NULL 时这是不可能的,因为 NULL != NULL 然后当值为 Null 时条件为 false。
我找不到编写此查询和处理 Null 比较的正确方法。
无法在合并条件下检查 Null,例如:
ON ((T.A IS NULL and S.A IS NULL) or T.A = S.A)
WHEN NOT MATCHED THEN
INSERT ROW
错误信息:
RIGHT OUTER JOIN 不能在没有连接两边的字段相等的条件下使用。
在WHERE 子句中也不能使用目标表引用,例如:
ON T.A = S.A
WHEN NOT MATCHED AND
S.A IS NOT NULL AND T.A IS NOT NULL
THEN
INSERT ROW
你有什么建议?另外,假设这两种方式都是可能的,BQ 会更划算吗?我想性能应该是一样的。我还假设我可以忽略插入成本。谢谢!
【问题讨论】:
-
它可以与
coalesce()一起使用吗?coalesce(T.A, '') = coalesce(S.A, '')。选择适合您的数据和数据类型的默认值。我也想知道这是否可行:coalesce( x = y, x is null and y is null ) is true. -
您也可以考虑通过将您的唯一字段散列在一起来创建代理键,然后您可以在该字段上执行 upsert。
标签: sql google-bigquery