BigQuery合并-如果未进行插入,则插入新行

时间:2019-11-27 06:38:58

标签: sql google-bigquery

我正在尝试在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更具成本效益的是什么?我想性能应该是一样的。我还假设我可以忽略插入费用。谢谢!

1 个答案:

答案 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)
  ]);

enter image description here

enter image description here

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;

enter image description here