我有一个产品表:
id createdOn UpdatedOn
和另外76列。
createdOn UpdatedOn
是TIMESTAMP
。
createdOn
是分区字段。
每个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 table
和row_number
表之间(尽管它是同一表)?我该如何解决?
答案 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使用两个表的解决方案要好得多。