BigQuery:从表连接引起的子选择中删除记录
Posted
技术标签:
【中文标题】BigQuery:从表连接引起的子选择中删除记录【英文标题】:BigQuery: Delete records from subselect caused by table join 【发布时间】:2019-03-19 17:26:57 【问题描述】:问题
所以我收集了一些进行连接的行,我需要通过查询删除这些行。有谁知道如何形成删除查询?我知道这听起来很容易,但找不到方法。
代码
SELECT * FROM (
SELECT
entity_key, min(actual_posting_time) as min_time
FROM
myTable
WHERE
_PARTITIONTIME BETWEEN TIMESTAMP("2018-12-01") AND TIMESTAMP("2018-12-04")
GROUP BY
entity_key
HAVING
COUNT(*) >= 2
)t1
LEFT JOIN
(
SELECT entity_key, actual_posting_time
FROM
myTable
WHERE _PARTITIONTIME BETWEEN TIMESTAMP("2018-12-01") AND TIMESTAMP("2018-12-04")
) t2
ON t1.entity_key = t2.entity_key
AND min_time <> t2.actual_posting_time )
因此,我想从上面的子选择中删除 myTable 中的每条记录。任何建议都非常感谢。
【问题讨论】:
哪个子查询?你有两个。 @RyanWilson 这次加入的结果是我有兴趣删除的结果。 ADELETE FROM TABLE WHERE entity_key IN (Your example query)
应该这样做,除非您将最外面的查询更改为仅选择 entity_key
而不是 *
是的,我在 SQL-Server 中工作,所以对于 bigquery 来说,有些东西似乎不存在,我想你可以按照你说的为每条记录创建唯一的列值,我可以如果这是您的决定,请为您提供一些帮助。
是的合并命令确实插入、更新和删除,这非常酷。我建议你仔细检查一下。
【参考方案1】:
据我了解查询,您希望保留具有相同 entity_key 的行的最旧记录。在这种情况下,您可以只 CONCAT
两个字段,如下所示:
DELETE * FROM myTable
WHERE CONCAT(CAST(entity_key as string), '_', CAST(actual_posting_time as string))
NOT IN (
SELECT
CONCAT(CAST(entity_key as string), '_', CAST(min(actual_posting_time) as min_time)
FROM
myTable
WHERE
_PARTITIONTIME BETWEEN TIMESTAMP("2018-12-01") AND TIMESTAMP("2018-12-04")
AND entity_key IS NOT NULL
GROUP BY
entity_key
HAVING
COUNT(*) >= 2
)
子查询中 WHERE 子句的第二个条件是由于 NOT IN
与标准 SQL 的语义,如 here 所述。使用一些公共数据集,您可以看到使用 select 命令将删除的结果:
#standardSQL
SELECT *
FROM `bigquery-public-data.austin_311.311_service_requests`
WHERE CONCAT(CAST(complaint_type as string), '_',CAST(status_change_date as string)) NOT IN (
SELECT CONCAT(CAST(complaint_type as string), '_',CAST(min(status_change_date) as string))
FROM `bigquery-public-data.austin_311.311_service_requests`
WHERE complaint_type is not null
GROUP BY complaint_type
)
实现此目的的另一种方法是使用EXISTS
,如下所示:
#standardSQL
WITH t1 AS (
SELECT complaint_type, MIN(status_change_date) AS min_date
FROM `bigquery-public-data.austin_311.311_service_requests`
GROUP BY complaint_type )
SELECT *
FROM `bigquery-public-data.austin_311.311_service_requests` AS t2
WHERE NOT EXISTS (
SELECT 1
FROM t1
WHERE t1.complaint_type = t2.complaint_type
AND t1.min_date = t2.status_change_date
)
请注意,对于这个公共表,结果会略有不同,因为有status_change_date
为NULL
的行。 NOT IN
不会删除这些,但NOT EXISTS
会删除。
【讨论】:
以上是关于BigQuery:从表连接引起的子选择中删除记录的主要内容,如果未能解决你的问题,请参考以下文章