BigQuery SQL:从日志表创建每日当前状态表

Posted

技术标签:

【中文标题】BigQuery SQL:从日志表创建每日当前状态表【英文标题】:BigQuery SQL: Create Daily Current Status Table from Log Table 【发布时间】:2021-02-11 11:16:01 【问题描述】:

我有一个记录任何状态变化的日志表。 例如:

Updated_at  Customer    Status
01/01/2020     A       Trial
01/01/2020     C       Trial
05/01/2020     B       Trial
06/03/2020     C       Free
15/03/2020     B       Full
05/04/2020     A       Free
07/05/2020     C       Full
10/09/2020     A       Full
10/09/2020     C       Remove

** Updated_at 是时间戳

我需要制作每日状态表,可以按天查看客户的当前状态:

Date         Customer   Status
01/01/2020      A   Trial
01/01/2020      C   Trial
02/01/2020      A   Trial
02/01/2020      C   Trial
|       
|       
05/01/2020      A   Trial
05/01/2020      B   Trial
05/01/2020      C   Trial
|
|       
06/03/2020      A   Trial
06/03/2020      B   Trial
06/03/2020      C   Free
|       
|       
15/03/2020      A   Trial
15/03/2020      B   Full
15/03/2020      C   Free
|       
|   
10/09/2020     A    Full
10/09/2020     B    Full
10/09/2020     C    Remove

也就是说,如果当天的状态没有变化,则从日志表中的最后一个变化日期开始记录状态。

我的尝试:

首先我创建一个包含一系列日期的列

接下来,我需要加入一个带日期的日志表

WITH CTE_DATES AS
(
SELECT
  *
FROM
  UNNEST( GENERATE_DATE_ARRAY( CURRENT_DATE(), DATE('2019-05-30'), INTERVAL -1 DAY) )  as Date
)
SELECT  d.date,
lt.Customer,
lt.Status,
extract (date from updated_at) as LT_Date
FROM `logTable` lt join CTE_DATES d on  extract (date from updated_at)<=d.Date

但是通过这种方法,我不仅可以在最后一个日志日期之前获得状态

Date       Customer     Status  Updated_at
12/09/2020      A       Trial   01/01/2020
12/09/2020      A       Free    05/04/2020
12/09/2020      A       Full    10/09/2020

联接表以获取每个日期序列中的最后一条记录的正确方法是什么?

【问题讨论】:

【参考方案1】:

我强烈建议通过每行创建日期来解决此问题。这使得将数据放在您想要的行中变得很简单。它也比一次生成所有日期然后使用连接和其他机制生成数据要高效得多:

with lt as (
      select lt.*,
             lead(updated_at, 1, current_date) over (partition by customer order by updated_at) as next_updated_at
      from `logTable` lt
     )
select dte, lt.customer, lt.status
from lt cross join
     unnest(generate_date_array(lt.updated_at,
                                date_add(lt.next_updated_at, interval -1 day),
                                interval 1 day)
                               ) dte;

【讨论】:

可能date_add(lt.next_updated_at, interval -1 day) 的意思是...... 嗨,通过这种方法,我得到的最后一天就像昨天而不是今天

以上是关于BigQuery SQL:从日志表创建每日当前状态表的主要内容,如果未能解决你的问题,请参考以下文章

有啥方法可以在 BigQuery 标准 SQL 脚本中遍历数据集中的所有表?

如何在 BigQuery SQL 中安全地参数化表/列名称?

BigQuery:计算每日分区表中的平均值

在从日志条目创建的会话表中查找并发用户

错误表中从 firebase 到 Bigquery 的日志

从 SQL 查询向 BigQuery 表添加多个分区列