Google bigquery 如何在BigQuery表中选择最新的分区?
我试图从日期分区的BigQuery表中的最新分区中选择数据,但该查询仍然从整个表中读取数据 我已经试过了(据我所知,BigQuery不支持Google bigquery 如何在BigQuery表中选择最新的分区?,google-bigquery,Google Bigquery,我试图从日期分区的BigQuery表中的最新分区中选择数据,但该查询仍然从整个表中读取数据 我已经试过了(据我所知,BigQuery不支持QUALIFY): 但这不起作用,会读取所有行 SELECT col from table WHERE _PARTITIONTIME = TIMESTAMP('YYYY-MM-DD') 其中,'YYYY-MM-DD'是一个特定的日期 但是,我以后需要运行这个脚本,但是表更新(以及\u PARTITIONTIME)是不规则的。有没有办法只从BigQuery中最
QUALIFY
):
但这不起作用,会读取所有行
SELECT col from table WHERE _PARTITIONTIME = TIMESTAMP('YYYY-MM-DD')
其中,'YYYY-MM-DD'
是一个特定的日期
但是,我以后需要运行这个脚本,但是表更新(以及\u PARTITIONTIME
)是不规则的。有没有办法只从BigQuery中最新的分区提取数据
2019年10月更新
对和的支持目前处于测试阶段(截至2019年10月)
您可以提交多个用分号分隔的语句,BigQuery现在可以运行它们了
见下面的例子
DECLARE max_date TIMESTAMP;
SET max_date = (
SELECT MAX(_PARTITIONTIME) FROM project.dataset.partitioned_table`);
SELECT * FROM `project.dataset.partitioned_table`
WHERE _PARTITIONTIME = max_date;
为那些喜欢在不检查上下文的情况下进行向下投票的人更新
我认为,这个答案被接受是因为它解决了OP的主要问题是否有一种方法可以只从BigQuery中最新的分区提取数据?
并且在评论中提到,很明显,BQ引擎仍然扫描所有行,但只返回基于最近分区的结果。正如问题注释中已经提到的-仍然可以通过编写逻辑脚本轻松解决问题-首先获取子查询的结果,然后在最终查询中使用它
试一试
或
列出包含以下内容的所有分区:
#standardSQL
SELECT
_PARTITIONTIME as pt
FROM
`[DATASET].[TABLE]`
GROUP BY 1
然后选择最新的时间戳
祝你好运:)
很抱歉,我在谷歌搜索中发现了这个老问题,我认为公认的答案是误导性的 从和运行的测试中我可以看出,接受的答案将不删除分区,因为子查询用于确定最近的分区: 需要对查询的多个阶段求值以解析谓词的复杂查询(例如内部查询或子查询)将不会从查询中删除分区 因此,尽管建议的答案将提供您期望的结果,但它仍然会查询所有分区。它将不忽略所有较旧的分区,只查询最新的分区 诀窍是使用或多或少的常量进行比较,而不是使用子查询。例如,如果
\u PARTITIONTIME
不是不规则的,而是每天的,请尝试通过获取昨天的分区来修剪分区,如下所示:
SELECT * FROM [dataset.partitioned_table]
WHERE _PARTITIONDATE = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
当然,这并不总是最新的数据,但在我的情况下,这恰好足够接近。如果需要今天的数据,请使用INTERVAL 0 DAY
,而不必担心查询将在当天尚未创建分区的部分返回0个结果
我很高兴知道是否有更好的解决办法来获得最新的分区 我找到了解决这个问题的方法。您可以使用with语句,选择最后几个分区并过滤掉结果。我认为这是更好的方法,因为:
WITH last_three_partitions as (select *, _PARTITIONTIME as PARTITIONTIME
FROM dataset.partitioned_table
WHERE _PARTITIONTIME > TIMESTAMP_SUB(CURRENT_TIMESTAMP(), INTERVAL 3 DAY))
SELECT col1, PARTITIONTIME from last_three_partitions
WHERE PARTITIONTIME = (SELECT max(PARTITIONTIME) from last_three_partitions)
您可以利用
\uuuu TABLES\uuuu
表列表来避免重新扫描所有内容或希望最新分区在~3天前。我做了split
和ordinal
的工作,以防我的表前缀由于某种原因在表名中出现多次
这应该适用于\u PARTITIONTIME
或\u TABLE\u SUFFIX
select * from `project.dataset.tablePrefix*`
where _PARTITIONTIME = (
SELECT split(table_id,'tablePrefix')[ordinal(2)] FROM `project.dataset.__TABLES__`
where table_id like 'tablePrefix%'
order by table_id desc limit 1)
我在一个不太受欢迎的问题中得到了这个答案,所以将它复制到这里,因为它是相关的(这个问题的页面浏览量越来越多): 米哈伊尔的回答如下(处理公共数据): 但问题似乎是这样的:
SELECT MAX(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) = (SELECT DATE(MAX(datehour)) FROM `fh-bigquery.wikipedia_v3.pageviews_2019` WHERE wiki='es')
AND wiki='es'
# 50.6 GB processed
。。。但对于小于50.6GB的方式
您现在需要的是某种脚本,分两步执行:
max_date = (SELECT DATE(MAX(datehour)) FROM `fh-bigquery.wikipedia_v3.pageviews_2019` WHERE wiki='es')
;
SELECT MAX(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) = {{max_date}}
AND wiki='es'
# 115.2 MB processed
您必须在BigQuery之外编写脚本,或者等待消息。这是一种折衷方案,它可以只查询几个分区,而不必求助于脚本,也不会因缺少固定日期的分区而失败
WITH latest_partitions AS (
SELECT *, _PARTITIONDATE AS date
FROM `myproject.mydataset.mytable`
WHERE _PARTITIONDATE > DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
)
SELECT
*
FROM
latest_partitions
WHERE
date = (SELECT MAX(date) FROM latest_partitions)
请注意,这将停止查询结果缓存(可能会影响成本)。此答案解决了
是否有办法仅从BigQuery中的最新分区提取数据?
问题!很明显,引擎仍然扫描所有行,但只基于最近的分区返回结果。正如问题注释中已经提到的-通过编写逻辑脚本仍然很容易解决问题-首先获取子查询的结果,然后在最终查询中使用它
当您手动探索数据时,脚本编写方法非常好,但在使用api客户机并将结果存储在目标表中时不起作用。在这些情况下,您仍然必须作为两个作业运行,第一个作业的输出用作第二个作业的输入,不幸的是:configuration.query.destinationTable无法为脚本设置
@LarsHaugseth您可以在脚本中使用INSERT或CREATE和REPLACE来避免无法设置目标表DECLARE的缺点是您无法在视图中使用它。您可以澄清一下它是如何工作的吗?有什么问题吗?我已经在下面做了评论,但这两个查询都不是只从最新的分区读取的。当我显式地键入last _partitiontime时,查询读取18MB。但当我尝试下面两个查询中的任何一个时,它们的读数为15.4GB。我现在知道了。谢谢你的更新!理解原因很有趣@felipe hoffa提到了一些关于缓存的内容,但这并不清楚。这样它就可以工作了,但有趣的是为什么它不能内联工作——在一个问题中,我想我现在明白了。很明显,但这是我的猜测。。。所以,当使用值时,分区会涉及get,bq引擎知道要扫描什么和什么
SELECT MAX(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) = DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
AND wiki='es'
# 122.2 MB processed
SELECT MAX(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) = (SELECT DATE(MAX(datehour)) FROM `fh-bigquery.wikipedia_v3.pageviews_2019` WHERE wiki='es')
AND wiki='es'
# 50.6 GB processed
max_date = (SELECT DATE(MAX(datehour)) FROM `fh-bigquery.wikipedia_v3.pageviews_2019` WHERE wiki='es')
;
SELECT MAX(views)
FROM `fh-bigquery.wikipedia_v3.pageviews_2019`
WHERE DATE(datehour) = {{max_date}}
AND wiki='es'
# 115.2 MB processed
WITH latest_partitions AS (
SELECT *, _PARTITIONDATE AS date
FROM `myproject.mydataset.mytable`
WHERE _PARTITIONDATE > DATE_SUB(CURRENT_DATE(), INTERVAL 7 DAY)
)
SELECT
*
FROM
latest_partitions
WHERE
date = (SELECT MAX(date) FROM latest_partitions)