我正在尝试在Google BigQuery中编写合并查询(属于ETL流程)。
我有 Source (登台)表和 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。
我找不到编写此查询和处理Nulls比较的正确方法。
不可能在合并条件下检查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更具成本效益的是什么?我想性能应该是一样的。我还假设我可以忽略插入费用。谢谢!
答案 0 :(得分:1)
您可以使用“魔术”数字或ID吗?
这有效:
CREATE OR REPLACE TABLE temp.target AS
SELECT * FROM UNNEST(
[STRUCT(1 AS A, 2 AS B, 3 AS C, 5 AS d)
, (null, 1, 3, 500)
]);
CREATE OR REPLACE TABLE temp.source AS
SELECT * FROM UNNEST(
[STRUCT(1 AS A, 2 AS B, 3 AS C, 100 AS d)
, (1, 1, 1, 1000)
, (null, null, null, 10000)
, (null, 1, 3, 10000)
]);
MERGE temp.target T
USING temp.source S
ON IFNULL(T.A, -9999999) = IFNULL(S.A, -9999999) and IFNULL(T.B, -9999999) = IFNULL(S.B, -9999999) and IFNULL(T.C, -9999999) = IFNULL(S.C, -9999999)
WHEN NOT MATCHED THEN
INSERT ROW;