如何在BigQuery上执行ETL以避免重复?

时间:2018-09-17 05:57:53

标签: sql google-bigquery

我有一个产品表: id createdOn UpdatedOn和另外76列。

createdOn UpdatedOnTIMESTAMPcreatedOn是分区字段。

每个ETL将存储中的记录加载到产品表中(追加)。

一旦ETL完成,我的产品表中就会出现重复。

示例:

id  createdOn,                    updatedOn,                stock, status
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10    5
3   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10     5
1   2018-09-14 14:14:24.305676   2018-09-14 14:14:24.305676  10     5
3   2018-09-14 14:14:24.305676   2018-09-15 10:00:00.000000  7     5

我要删除重复的id。最近的updatedOn记录需要保留,其余的需要除去。

我按照这里的建议行事:Google BQ - how to upsert existing data in tables? 这是我的查询:

   DELETE FROM `storage.prodcuts` AS d
   WHERE (SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id ORDER BY updatedOn DESC)
           FROM `storage.prodcuts` AS d2
           WHERE d.id = d2.id ) > 1;  

这不起作用:

  

错误:没有引用其他表的相关子查询   受支持,除非可以将它们解相关,例如通过转换   他们成为有效的JOIN。

也尝试过:

 delete FROM `storage.prodcuts` as p
  ( SELECT ROW_NUMBER() OVER (PARTITION BY createdOn, id  order by updatedOn DESC) as rn , id FROM `storage.prodcuts` ) as t
WHERE t.rn> 1 and p.id=t.id;  

礼物:

  

语法错误:[[:3:7]处出现意外的“(”

我假设BigQuery希望我加入delete tablerow_number表之间(尽管它是同一表)?我该如何解决?

2 个答案:

答案 0 :(得分:0)

维护两个表,您现在拥有一个表:所有表中都有另一个表,即清理版本,您只能基于id列从第一表到第二表进行合并。这样,最新行将位于第二个表中,并使用MERGE语句将其始终覆盖。

您现在甚至可以Schedule Queries,因此,您的MERGE语句可以每X次自动执行一次。

答案 1 :(得分:0)

如果您没有包含重复的(id,updatedOn)对的行,或者可以通过其他方式解析此类重复项,则可以执行以下类似的简单操作来实现:

DELETE FROM `storage.prodcuts` AS d
WHERE EXISTS (SELECT 1 FROM `storage.prodcuts` p2 
              WHERE p2.id = d.id AND p2.updatedOn > d.updatedOn)

但是从可维护性的角度来看,我认为Pentium10使用两个表的解决方案要好得多。