LeetCode(数据库)- 报告系统状态的连续日期

题目链接:点击打开链接

题目大意:略。

解题思路:解决方案(2)代码看似多,但是思路很清晰,一步一步做下来;解决方案(1)变量 @id 中间虽然使用了 UNION ALL,但是还是会继续上面的数值接着来,而不是重新从 0 开始噢。

AC 代码

-- 解决方案(1)
SELECT period_state, MIN(date) AS start_date, MAX(date) AS end_date
FROM
( 
SELECT fail_date AS date, 
'failed' AS period_state,
IF(DATEDIFF(@pre, @pre := fail_date) = -1, @id, @id := @id+1) AS id
FROM Failed a1, (SELECT @id :=0, @pre := NULL) b1
UNION ALL
SELECT success_date AS date, 
'succeeded' AS period_state,
IF(DATEDIFF(@pre, @pre := success_date) = -1, @id, @id := @id+1) AS id
FROM Succeeded a2, (SELECT @id :=0, @pre := NULL) b2
) t3
WHERE date BETWEEN "2019-01-01" AND "2019-12-31"
GROUP BY t3.id
ORDER BY start_date

-- 解决方案(2)
WITH t1 AS(SELECT CAST(@num := @num + IF(@pre IS NOT NULL AND DATEDIFF(success_date, @pre) = 1, 0, 1) AS SIGNED) rk, @pre := success_date dt, 1 mark
FROM Succeeded, (SELECT @pre:=null, @num:=0) init
WHERE success_date BETWEEN '2019-01-01' AND '2019-12-31'),

t2 AS(SELECT rs2.minn dt1, rs1.maxn dt2, rs1.rk, rs1.mark
FROM 
(SELECT MAX(dt) maxn, rk, mark
FROM t1
GROUP BY rk) rs1
JOIN
(SELECT MIN(dt) minn, rk, mark
FROM t1
GROUP BY rk) rs2
ON rs1.rk = rs2.rk),

t3 AS(SELECT CAST(@num := @num + IF(@pre IS NOT NULL AND DATEDIFF(fail_date, @pre) = 1, 0, 1) AS SIGNED) rk, @pre := fail_date dt, 0 mark
FROM Failed, (SELECT @pre:=null, @num:=0) init
WHERE fail_date BETWEEN '2019-01-01' AND '2019-12-31'),

t4 AS(SELECT rs2.minn dt1, rs1.maxn dt2, rs1.rk, rs1.mark
FROM 
(SELECT MAX(dt) maxn, rk, mark
FROM t3
GROUP BY rk) rs1
JOIN
(SELECT MIN(dt) minn, rk, mark
FROM t3
GROUP BY rk) rs2
ON rs1.rk = rs2.rk)

SELECT IF(mark = 0, 'failed', 'succeeded') period_state, dt1 start_date, dt2 end_date
FROM (SELECT * FROM t2 UNION ALL SELECT * FROM t4) RS
ORDER BY dt1
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

放羊的牧码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值