繁体   English   中英

BIG QUERY SQL:在带有移动参考的滑动时间窗口上标记日期

[英]BIG QUERY SQL: Tagging dates on a sliding time window with a moving reference

此职位的目的是什么?

作为一个团队,我们希望根据以下内容将每个日期标记为“真”或“假”;

1)visit_date是访客的第1次造访 ,然后为TRUE

2)对于第一个访问日期之后的所有visit_date

一个)相比于最后VISIT_DATE这是TRUE(特此LAST TRUE)时,如果VISIT_DATE是最后一个真正的30天前视窗内; 然后FALSE

访客A 访客B

我使用什么数据?

包含访问者和visit_date的网站数据。

记录访客创建的每个新会话的visit_date。 我们操纵数据以使每个访问者每个日期仅获得一条记录。

问题:

简单的LAG功能和LEAD功能没有帮助,因为;

1)给定新的TRUE标记后, LAST TRUE的参考位置不断更改

a)我们必须检查的记录数,以确保访问者进行的LAST TRUE更改。 下一个TRUE可以在2行或15行之后; 这取决于访客。

实际上,我们无法在BigQuery中创建一个循环

  1. 检查visit_date是否符合条件

  2. 如果确实将其标记为TRUE,则还将LAST TRUE引用更改为此访问日期

  3. 重复此过程直到访客的最后记录

使用的查询:

第一个表(table_id)只是为了获得以下计算

访客唯一标识符

visit_date参观日

plus_30_days 30天+访问天数

lag_value上一行的visit_date的

lead_value下面一行的visit_date的

为了易于使用,所有值均转换为DAYOFYEAR()

基于上表,我使用了以下查询

 SELECT    *
 , CASE WHEN lag_value IS NULL THEN 1 
        WHEN visit_date - lag_value > 30 THEN 1 
        WHEN lead_value IS NULL THEN 1 
        ELSE 0 END AS true_false
 FROM [project_id:dataset.table_id] 
 ORDER BY visitor, visit_date

OUTPUT:

绿色框应为TRUE OUTPUT

因为

访客C

所采取的行动:

1)我尝试了LEAD和LAG功能

2)检查网上,可以转换为BIGQUERY >>的普通SQL函数找不到循环函数

3)问我的团队负责人>>相同问题

4)最多3个小时的实验>>相同的输出

供参考的表(未格式化)

visitor_id  file_date   plus_30_days    lag_value   lead_value  true_false
A   1   31  null    38  1
A   38  68  1   41  1
A   41  71  38  65  0
A   65  95  41  76  0
A   76  106 65  null    1
B   90  120 null    122 1
B   122 152 90  null    1
C   123 153 null    134 1
C   134 164 123 163 0
C   163 193 134 183 0
C   183 213 163 217 0
C   217 247 183 null    1
D   245 275 null    256 1
D   256 286 245 262 0
D   262 292 256 275 0
D   275 305 262 279 0
D   279 309 275 null    1
E   279 309 null    310 1
E   310 340 279 341 1
E   341 5   310 null    1

请尝试以下。

SELECT visitor_id, file_date, true_false FROM JS(    // input table
( SELECT visitor_id, GROUP_CONCAT(STRING(100000 + file_date), ';') AS visits FROM
    (SELECT 'A' AS visitor_id, 1 AS file_date), (SELECT 'A' AS visitor_id, 38 AS file_date), (SELECT 'A' AS visitor_id, 41 AS file_date), (SELECT 'A' AS visitor_id, 65 AS file_date),
    (SELECT 'A' AS visitor_id, 76 AS file_date), (SELECT 'B' AS visitor_id, 90 AS file_date), (SELECT 'B' AS visitor_id, 122 AS file_date), (SELECT 'C' AS visitor_id, 123 AS file_date),
    (SELECT 'C' AS visitor_id, 134 AS file_date), (SELECT 'C' AS visitor_id, 163 AS file_date), (SELECT 'C' AS visitor_id, 183 AS file_date), (SELECT 'C' AS visitor_id, 217 AS file_date),
    (SELECT 'D' AS visitor_id, 245 AS file_date), (SELECT 'D' AS visitor_id, 256 AS file_date), (SELECT 'D' AS visitor_id, 262 AS file_date), (SELECT 'D' AS visitor_id, 275 AS file_date),
    (SELECT 'D' AS visitor_id, 279 AS file_date), (SELECT 'E' AS visitor_id, 279 AS file_date), (SELECT 'E' AS visitor_id, 310 AS file_date), (SELECT 'E' AS visitor_id, 341 AS file_date)  
  GROUP BY visitor_id
) ,
// input columns
visitor_id, visits,
// output schema
"[{name: 'visitor_id', type: 'string'},
{name: 'file_date', type: 'integer'},
{name: 'true_false', type: 'integer'}]",
// function
"function(r, emit){
  var visits = r.visits.split(';');
  visits.sort();
  plus_30_days = 0;
  for (var i = 0; i < visits.length; i++) { 
    file_date = parseInt(visits[i]) - 100000;
    true_false = 0;
    if (file_date > plus_30_days) {
      plus_30_days = file_date + 30;
      true_false = 1;
    }
      emit({
        visitor_id: r.visitor_id,
        file_date: file_date,
        true_false: true_false
      });      
  }
 }")

希望这给您一个好的开始
请注意:以上示例使用了未记录的内联版本的JavaScript UDF,到目前为止,该版本非常适合快速演示/共享/尝试代码,但是...未记录,因此不受支持
为了在生产环境中使用上述示例,您最好对其进行修改以符合BigQuery用户定义函数文档(很少有非常简单的调整)。

暂无
暂无

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

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