Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql BigQuery-删除where和in子句中的两列_Sql_Google Cloud Platform_Google Bigquery - Fatal编程技术网

Sql BigQuery-删除where和in子句中的两列

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

我有一个从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_在时间戳处批处理_——这是一个批处理蒸汽,所以批处理开始时间的时间戳 上述列的示例数据:

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
          )