我试图从日期分区的BigQuery表中的最新分区中选择数据,但查询仍然从整个表中读取数据.
我试过(据我所知,BigQuery不支持QUALIFY):
SELECT col FROM table WHERE _PARTITIONTIME = (
SELECT pt FROM (
SELECT pt, RANK() OVER(ORDER by pt DESC) as rnk FROM (
SELECT _PARTITIONTIME AS pt FROM table GROUP BY 1)
)
)
WHERE rnk = 1
);
Run Code Online (Sandbox Code Playgroud)
但这不起作用并读取所有行.
SELECT col from table WHERE _PARTITIONTIME = TIMESTAMP('YYYY-MM-DD')
Run Code Online (Sandbox Code Playgroud)
'YYYY-MM-DD'特定日期在哪里工作.
但是,我需要在将来运行此脚本,但表更新(和_PARTITIONTIME)是不规则的.有没有办法只从BigQuery的最新分区中提取数据?
Mik*_*ant 15
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;
Run Code Online (Sandbox Code Playgroud)
更新那些喜欢在不检查上下文的情况下投票的人等。
我认为,这个答案被接受是因为它解决了 OP 的主要问题,Is there a way I can pull data only from the latest partition in BigQuery?并且在评论中提到很明显 BQ 引擎仍然扫描所有行,但仅基于最近的分区返回结果。正如在问题评论中已经提到的那样 -Still something that easily to be addressed by having that logic scripted - first getting result of subquery and then use it in final query
尝试
SELECT * FROM [dataset.partitioned_table]
WHERE _PARTITIONTIME IN (
SELECT MAX(TIMESTAMP(partition_id))
FROM [dataset.partitioned_table$__PARTITIONS_SUMMARY__]
)
Run Code Online (Sandbox Code Playgroud)
或者
SELECT * FROM [dataset.partitioned_table]
WHERE _PARTITIONTIME IN (
SELECT MAX(_PARTITIONTIME)
FROM [dataset.partitioned_table]
)
Run Code Online (Sandbox Code Playgroud)
我找到了这个问题的解决方法。您可以使用with语句,选择最后几个分区并过滤掉结果。我认为这是更好的方法,因为:
最后 3 个分区扫描的示例:
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)
Run Code Online (Sandbox Code Playgroud)
小智 5
列出所有分区:
#standardSQL
SELECT
_PARTITIONTIME as pt
FROM
`[DATASET].[TABLE]`
GROUP BY 1
Run Code Online (Sandbox Code Playgroud)
然后选择最新的时间戳。
祝你好运 :)
https://cloud.google.com/bigquery/docs/querying-partitioned-tables
不好意思,这个老问题被挖掘出来了,但是它出现在Google搜索中,我认为被接受的答案具有误导性。
据我从文档和正在运行的测试中得知,接受的答案不会修剪分区,因为使用子查询来确定最新的分区:
需要解析查询的多个阶段才能解析谓词的复杂查询(例如内部查询或子查询)将不会从查询中删除分区。
因此,尽管建议的答案将提供您期望的结果,但仍将查询所有分区。它不会忽略所有较旧的分区,而只会查询最新的分区。
诀窍是使用或多或少的常量进行比较,而不是使用子查询。例如,如果_PARTITIONTIME不是日常事务而是日常事务,请尝试通过获取昨天的分区来修剪分区,如下所示:
SELECT * FROM [dataset.partitioned_table]
WHERE _PARTITIONDATE = DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY)
Run Code Online (Sandbox Code Playgroud)
当然,这并不总是最新的数据,但就我而言,这恰好足够接近。INTERVAL 0 DAY如果您需要今天的数据,请使用此参数,而不必关心查询在一天中尚未创建分区的那部分返回0个结果。
我很高兴了解是否有更好的解决方法来获取最新的分区!
| 归档时间: |
|
| 查看次数: |
6025 次 |
| 最近记录: |