这个问题我正在尝试在 HackerRank 上解决。在这个问题中,我必须对连续的日期进行分组。当两个日期之间的差为 1 时,两个日期是连续的,并且在此问题陈述中,开始日期和结束日期始终是连续的。
我的方法是将连续的日期分组。为了识别连续日期,我使用变量
@rn
。当 current start
日期等于之前的 end date
时,我将拥有相同的 rn
,否则我将递增 rn
。然后我想按 rn
进行分组,并从具有相同 min(start date)
的每个组中获取 max(end date
和 rn
)。但在实现这个逻辑之前,我遇到了一个问题,即即使 MySQL 中 @rn
子句内的 when
条件为 false
,case
变量也会递增。
set @rn = 0;
with tasks as (
select distinct Start_Date, End_Date
from Projects
order by Start_Date
)
select
Start_Date, End_Date,
case
when lag(End_Date, 1) over(Order by Start_Date) != Start_Date then @rn:=@rn+1
else @rn
end as cnt
from tasks
在上述查询中,即使
@rn := @rn+1
条件为 when
,也会执行 false
。
我遇到了这个问题,试图解决来自HackeRank的问题。
如果有人能解释为什么即使条件是
@run := @rn+1
也会执行false
那就太好了。
这是上述查询针对指定问题生成的输出:
2015-10-01 2015-10-02 0
2015-10-02 2015-10-03 1
2015-10-03 2015-10-04 2
2015-10-04 2015-10-05 3
2015-10-11 2015-10-12 24
2015-10-12 2015-10-13 5
2015-10-15 2015-10-16 24
2015-10-17 2015-10-18 24
2015-10-19 2015-10-20 24
2015-10-21 2015-10-22 24
2015-10-25 2015-10-26 24
...
2015-10-01 2015-10-02 1
2015-10-02 2015-10-03 1
2015-10-03 2015-10-04 1
2015-10-04 2015-10-05 1
2015-10-11 2015-10-12 2
2015-10-12 2015-10-13 2
2015-10-15 2015-10-16 3
2015-10-17 2015-10-18 4
2015-10-19 2015-10-20 5
2015-10-21 2015-10-22 6
2015-10-25 2015-10-26 7
...
鉴于您使用的是 MySQL 8+,它提供了窗口函数,甚至不需要求助于使用会话/用户变量。在窗口函数的帮助下,您的查询实际上很容易表达:
WITH cte AS (
SELECT *, CASE WHEN LAG(End_Date, 1, End_Date) OVER (ORDER BY Start_Date) != Start_Date
THEN 1 ELSE 0 END AS cnt
FROM tasks
)
SELECT Start_Date, End_Date, 1 + SUM(cnt) OVER (ORDER BY Start_Date) AS total
FROM cte
ORDER BY Start_Date;