在实现更简单的业务逻辑时,我问自己,如果业务需求如下所示,我会怎么做:
业务需求
假设表中有一个客户id和一个访问时间戳。现在,业务部门希望在客户第一次访问之后,以及自客户获得上一次促销资格后至少n天(在本例中,让我们为n设置7)之后的每次首次访问时,向客户发送一次特别促销。
示例数据
+--------+-------------+---------------------------+
| row_no | customer_id | visit_ts |
+--------+-------------+---------------------------+
| 1 | A | 2020-01-01 07:00:00.00000 |
| 2 | A | 2020-01-01 09:00:00.00000 |
| 3 | A | 2020-01-02 17:00:00.00000 |
| 4 | A | 2020-01-08 20:00:00.00000 |
| 5 | A | 2020-01-11 11:30:00.00000 |
| 6 | A | 2020-01-16 08:00:00.00000 |
| 7 | B | 2020-01-11 10:00:00.00000 |
| 8 | B | 2020-01-16 10:00:00.00000 |
| 9 | B | 2020-01-18 11:00:00.00000 |
| 10 | B | 2020-01-20 11:00:00.00000 |
| 11 | B | 2020-01-27 09:00:00.00000 |
+--------+-------------+---------------------------+
期望结果
客户a:第1、4、6排
顾客b:第7、9、11排
到目前为止我试过的
使用滞后函数或窗口框架查找每个记录的前一次访问非常简单。在下一步中,我们可以借助timestamp diff函数来计算visit_ts和prev_visit_ts之间的差异,它给出了这两个时间戳之间的秒数。
最后,我们可以再次使用窗口函数来计算该值的运行和:
SELECT *,
# Step 3: Calc running sum of seconds since last visit - how to reset after reaching a threshold?
SUM(sec_since_last_visit) OVER (PARTITION BY customer_id ORDER BY visit_ts ROWS UNBOUNDED PRECEDING) as running_sum
FROM (
SELECT
*,
# Step 2: Calc the amount of seconds between this and prev visit
TIMESTAMP_DIFF(visit_ts,prev_visit_ts,SECOND) AS sec_since_last_visit
FROM (
SELECT
*,
# Step 1: Calc visit_ts of previous visit
LAG(visit_ts) OVER(PARTITION BY customer_id ORDER BY visit_ts) AS prev_visit_ts
FROM
table ) )
什么不起作用?
我找不到解决办法:我需要以某种方式重置运行总和一旦达到阈值7天。bigquery中没有像teradata中那样的reset when子句。也不能在bigquery中嵌套分析函数或使用递归。在当前行周围使用逻辑范围的选项只允许静态值,我想这也没有帮助。
在bigquery中有没有解决这个问题的方法(不使用存储过程)?
当然,在python或java等编程语言中,使用迭代或递归方法可以很容易地解决这个问题。但是,我特别感兴趣的是,在bigquery标准sql中是否有解决这个问题的方法,以及这个解决方案是什么样子的。
暂无答案!
目前还没有任何答案,快来回答吧!