桌子
客户编号 | 登录 |
---|---|
1 | 2016-03-01 |
1 | 2016-03-02 |
1 | 2016-03-03 |
1 | 2016-03-05 |
1 | 2016-03-06 |
1 | 2016-03-07 |
1 | 2016-03-08 |
我的做法是
使用自连接来创建滞后(我使用自连接是因为直接使用前导和滞后在这里不起作用)。
现在我需要创建一个列,检查前一个日期是否为空然后为0,否则计数1,2,3,.....如果前一个日期再次为0,则再次从零开始计数。
客户编号 | 登录 | 上次日期 | 连续_日_标志 |
---|---|---|---|
1 | 2016-03-01 | 空 | 0 |
1 | 2016-03-02 | 2016-03-01 | 1 |
1 | 2016-03-03 | 2016-03-02 | 2 |
1 | 2016-03-05 | 空 | 0 |
1 | 2016-03-06 | 2016-03-05 | 1 |
1 | 2016-03-07 | 2016-03-06 | 2 |
1 | 2016-03-08 | 2016-03-08 | 3 |
-- 现在我可以找到最大值
consecutive_day_flag
并将该列命名为最高连续天数。
最高连续日 |
---|
3 |
如何处理创建
consecutive_day_flag
列的第 2 步?
或者请建议任何更好的方法。
我已经尝试过以上方法。
这是一个“间隙和孤岛”问题。解决该问题的一种方法是使用 row_number()
和连续天数的运行总和 :
WITH cte AS (
select *,
CASE WHEN DATEDIFF(DAY, login, LEAD(login, 1, login) over (PARTITION BY customer_id ORDER BY login)) = 1 THEN 1 ELSE 0 END AS day_diff
from mytable
),
cte2 as (
SELECT *, row_number() over (partition by customer_id order by login)
- sum(day_diff) over (partition by customer_id, day_diff order by login) AS grp
FROM cte
),
cte3 AS (
SELECT customer_id, grp, COUNT(1) AS consecutive_day
FROM cte2
GROUP BY customer_id, grp
)
SELECT customer_id, MAX(consecutive_day) AS highest_consecutive_day
FROM cte3
GROUP BY customer_id;
演示在这里