Sql BigQuery-删除where和in子句中的两列
我有一个从OLTP数据库到BQ的数据流。所以,如果任何一行被更新,BQ将在两个不同的行中同时包含旧记录和新记录。因此,我有一个查询来消除重复数据,但我希望至少每天从BQ中删除一次旧值 这是我的select查询,它将为我提供最新的记录 选择不同的o.\U sdc\U序列 来自'my production.bqtest.mytbl`o' 内连接 选择id, 最大sdc顺序如下所示, 最大sdc批次为批次 来自'my-production.bqtest.mytbl` 按id分组oo ON o.id=oo.id 和o._sdc_序列=oo.seq 和o.(sdc)批处理的(at=oo.batch) id-整数主键 sdc_序列-数据插入BQ时的unix时间戳 _sdc_在时间戳处批处理_——这是一个批处理蒸汽,所以批处理开始时间的时间戳 上述列的示例数据:Sql BigQuery-删除where和in子句中的两列,sql,google-cloud-platform,google-bigquery,Sql,Google Cloud Platform,Google Bigquery,我有一个从OLTP数据库到BQ的数据流。所以,如果任何一行被更新,BQ将在两个不同的行中同时包含旧记录和新记录。因此,我有一个查询来消除重复数据,但我希望至少每天从BQ中删除一次旧值 这是我的select查询,它将为我提供最新的记录 选择不同的o.\U sdc\U序列 来自'my production.bqtest.mytbl`o' 内连接 选择id, 最大sdc顺序如下所示, 最大sdc批次为批次 来自'my-production.bqtest.mytbl` 按id分组oo ON o.id=o
select id,
_sdc_sequence,
_sdc_batched_at
FROM `my-production.bqtest.mytbl`
ID: 2741332
_sdc_sequence: 1565726907840002084
_sdc_batched_at: 2019-08-13 21:01:07.687 UTC
我想删除旧的记录,我可以用最新的行进行每日的表轮换,但是如果我更改了表结构,我使用的ETL工具将无法工作
我尝试了下面的查询,但它也删除了一些有效行
从'my production.bqtest.mytbl'中删除,其中_sdc_序列不在
选择不同的o.\U sdc\U序列
来自'my production.bqtest.mytbl`o'
内连接
选择id,
最大sdc顺序如下所示,
最大sdc批次为批次
来自“my production.bqtest.mytbl”
按id分组oo
ON o.id=oo.id
和o._sdc_序列=oo.seq
和o.(sdc)批处理的(at=oo.batch)
因为我有两行具有相同的序列id,所以我需要用where _sdc_sequence not in+max _sdc_batched_at过滤掉它
或任何其他更好的查询来执行此操作 如果希望每个id只保留一行,那么元组语法可能是最简单的。保存的记录:
select t.*
from `my-production.bqtest.mytbl` t
where (id, _sdc_sequence) in
(select t2.id, MAX(t2._sdc_sequence)
from `my-production.bqtest.mytbl` t2
group by t2.id
);
根据你的描述,我不确定这批货和这个问题有什么关系,所以我把它漏掉了
您可以使用not in或类似逻辑将其转换为删除:
delete from `my-production.bqtest.mytbl` t
where (id, _sdc_sequence) not in
(select t2.id, MAX(t2._sdc_sequence)
from `my-production.bqtest.mytbl` t2
group by t2.id
);
您也可以将其表述为:
delete from `my-production.bqtest.mytbl` t
where _sdc_sequence <
(selectd max(t2._sdc_sequence)
from `my-production.bqtest.mytbl` t2
where t2.id = t.id
);
在select查询的列列表中使用a以避免输入的子查询必须只有一个输出列错误只需在where检查和子查询中的两个字段处进行合并,即可将它们转换为具有唯一值的单个字段。在运行delete之前,请确保它们是唯一的:
select t.*
from `my-production.bqtest.mytbl` t
where concat(id, _sdc_sequence) in
(select concat(t2.id, MAX(t2._sdc_sequence))
from `my-production.bqtest.mytbl` t2
group by t2.id
)
谷歌Bigquery等平台在硬删除方面并不是很好的性能解决方案。您是否考虑过软删除解决方案,即在大查询中收集增量提要的所有版本,并创建使用分区函数(如行号)抑制所有非最新版本行的特定视图?是的,即使我不愿意这样做,但这是要求,我需要实现。这就是为什么我每天都这样做一次。然后它将减少我的查询执行时间。使用deletes对目标BQ表进行变异的要求还意味着您每次运行硬删除vis-a-vis时都会丢失所有非最近记录的历史记录,使用物化视图,您将获得目标BQ表上完成的所有流插入的完整数据沿袭。感谢您的回答,我收到此错误,输入的子查询在[4:12]@Bhuvanesh处必须只有一个输出列。事实上,我测试了使用in和元组的代码,这是肯定的,而且它是有效的。在任何情况下,这也可以使用相关子查询来表示。我不推荐这种方法。它要求所有数据类型都是字符串,但也假设在连接字符串后结果中没有歧义。例如,CONCATABC,DEF与CONCATABCD,EF的结果相同。
select t.*
from `my-production.bqtest.mytbl` t
where concat(id, _sdc_sequence) in
(select concat(t2.id, MAX(t2._sdc_sequence))
from `my-production.bqtest.mytbl` t2
group by t2.id
)