繁体   English   中英

Google BigQuery SQL:如何用日期填充表格中的空白?

[英]Google BigQuery SQL: How to fill in gaps in a table with dates?

数据表

日期 顾客 订阅
20/02/2020 一个 自由的
21/02/2020 一个 自由的
2020 年 2 月 22 日 一个 自由的
2020 年 2 月 23 日 自由的
2020 年 3 月 23 日 一个 满的
2020 年 1 月 3 日 满的
2020 年 1 月 3 日 一个 满的
2020 年 2 月 3 日 一个 满的

需要用前一个日期的值来填补日期的空白

Output

日期 顾客 最后订阅
20/02/2020 一个 自由的
21/02/2020 一个 自由的
2020 年 2 月 22 日 一个 自由的
2020 年 3 月 23 日 一个 满的
2020 年 3 月 23 日 自由的
2020 年 2 月 24 日 一个 满的
2020 年 2 月 24 日 自由的
2020 年 2 月 25 日 一个 满的
2020 年 2 月 25 日 自由的
2020 年 2 月 26 日 一个 满的
2020 年 2 月 26 日 自由的
2020 年 2 月 27 日 一个 满的
2020 年 2 月 27 日 自由的
2020 年 2 月 28 日 一个 满的
2020 年 2 月 28 日 自由的
2020 年 1 月 3 日 一个 满的
2020 年 1 月 3 日 满的
2020 年 2 月 3 日 一个 满的
2020 年 2 月 3 日 满的

我找到了一个类似的解决方案Duplicate groups of records to fill multiple date gaps in Google BigQuery ,但它不适合,因为在我的示例中,每个Customer都有不同的开始日期。

考虑下面

with temp as (
  select customer, dates from (    
    select customer, min(dates) min_date, max(dates) max_date
    from `project.dataset.table`
    group by customer
  ), unnest(generate_date_array(min_date, max_date)) dates
)
select customer, dates, 
  first_value(subscription ignore nulls) over win as subscription
from temp a
left join `project.dataset.table` b
using(customer, dates)
window win as (partition by customer order by dates desc rows between current row and unbounded following)
# order by dates, customer          

如果适用于我们的问题中的示例数据 - output 是

在此处输入图像描述

我强烈建议使用这样的lead()方法:

with data as (
      select cast('2020-02-20' as date) as dates, 'A' as customer, 'free' as subscription union all
      select cast('2020-02-21' as date) as dates, 'A' as customer, 'free' as subscription union all
      select cast('2020-02-22' as date) as dates, 'A' as customer, 'free' as subscription union all
      select cast('2020-02-23' as date) as dates, 'B' as customer, 'free' as subscription union all
      select cast('2020-03-23' as date) as dates, 'A' as customer, 'full' as subscription union all
      select cast('2020-03-01' as date) as dates, 'B' as customer, 'full' as subscription union all
      select cast('2020-03-01' as date) as dates, 'A' as customer, 'full' as subscription union all
      select cast('2020-03-02' as date) as dates, 'A' as customer, 'full' as subscription 
)
select d.customer, dy, d.subscription
from (select d.*,
             lead(dates) over (partition by customer order by dates) as next_date
      from data d
     ) d cross join
     unnest(generate_date_array(d.dates, coalesce(date_add(d.next_date, interval -1 day), d.dates), interval 1 day)) dy;

我推荐这样做的原因是因为unnest()发生在单行中,所以匹配日期没有数据移动。 另外没有 window function 需要填写subscription

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM