在 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 计划查询(脚本)循环:需要保存目标表,但由于设置了目标表,运行失败

使用 bigrquery 的 R 循环中的 BigQuery 超时错误

BigQuery 中的 SUM 循环

错误标量子查询在 bigquery 中查询 json 文件

在 bigquery 上查询项目中的所有数据集和表?

在 bigquery 中查询多个基于日期的表