在 bigquery 中循环查询
Posted
技术标签:
【中文标题】在 bigquery 中循环查询【英文标题】:Loop over query in bigquery 【发布时间】:2020-11-25 14:18:39 【问题描述】:我正在尝试遍历查询结果并合并结果。
我想遍历一个叫做滚动日期的变量,它给出了一个相差 30 天的日期数组。
DECLARE rollingdate ARRAY<DATE>;
SET rollingdate = ( GENERATE_DATE_ARRAY(CURRENT_DATE(), DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY), INTERVAL -30 DAY) );
我的表按 DATE 分区,我想循环从滚动日期开始的两个连续日期并合并所有结果
select *, rollingdate[0]
from table
where date > rollingdate[1] and date < rollingdate[0]
union all
select *, rollingdate[1]
from table
where date > rollingdate[2] and date < rollingdate[1]
如何在 bigquery 中实现这一点?我尝试使用 bigquery 脚本,但它们不接受子查询..
【问题讨论】:
您只是想添加滚动日期吗?不知道你为什么要分割你的查询只是为了再次联合它?任何给定的日期将只属于 1 个时间段 【参考方案1】:你可以试试EXECUTE IMMEDIATE
:
DECLARE i INT64 DEFAULT 1;
DECLARE dsql STRING DEFAULT '';
DECLARE rollingdate ARRAY<DATE>;
SET rollingdate = ( GENERATE_DATE_ARRAY(CURRENT_DATE(), DATE_SUB(CURRENT_DATE(), INTERVAL 365 DAY), INTERVAL -30 DAY) );
WHILE i <= 2
DO
SET dsql = dsql || " select *, '" || rollingdate[ORDINAL(i)] || "' from table where date > '" || rollingdate[ORDINAL(i+1)] || "' and date < '" || rollingdate[ORDINAL(i)] || "' union all";
SET i = i + 1;
END WHILE;
SET dsql = SUBSTR(dsql, 1, LENGTH(dsql) - LENGTH(' union all'));
EXECUTE IMMEDIATE dsql;
【讨论】:
【参考方案2】:这样的方法应该没问题:
with
dates as (
select * from unnest(generate_date_array(current_date, date_sub(current_date(), interval 365 DAY), interval -30 day)) as date
),
date_start_end as (
select lag(date,1) over(order by date asc) as begin_date, date as end_date
from dates
)
select table.*, end_date
from table
inner join date_start_end where date between begin_date and end_date
您可能需要根据您的日期范围是包含还是排除进行调整。
正如我在评论中提到的,table
中的任何日期都只会出现在您的 rollingdate
间隔中的 1 个中。当您可以对集合执行操作并避免循环时,SQL 的性能会更高。
【讨论】:
以上是关于在 bigquery 中循环查询的主要内容,如果未能解决你的问题,请参考以下文章
BigQuery 计划查询(脚本)循环:需要保存目标表,但由于设置了目标表,运行失败