[英]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.