leetcode1225. 报告系统状态的连续日期(sql自定义变量)

https://leetcode-cn.com/problems/report-contiguous-dates/
Table: Failed

±-------------±--------+
| Column Name | Type |
±-------------±--------+
| fail_date | date |
±-------------±--------+
该表主键为 fail_date。
该表包含失败任务的天数.
Table: Succeeded

±-------------±--------+
| Column Name | Type |
±-------------±--------+
| success_date | date |
±-------------±--------+
该表主键为 success_date。
该表包含成功任务的天数.

系统 每天 运行一个任务。每个任务都独立于先前的任务。任务的状态可以是失败或是成功。
编写一个 SQL 查询 2019-01-01 到 2019-12-31 期间任务连续同状态 period_state 的起止日期(start_date 和 end_date)。即如果任务失败了,就是失败状态的起止日期,如果任务成功了,就是成功状态的起止日期。
最后结果按照起始日期 start_date 排序
查询结果样例如下所示:

Failed table:
±------------------+
| fail_date |
±------------------+
| 2018-12-28 |
| 2018-12-29 |
| 2019-01-04 |
| 2019-01-05 |
±------------------+

Succeeded table:
±------------------+
| success_date |
±------------------+
| 2018-12-30 |
| 2018-12-31 |
| 2019-01-01 |
| 2019-01-02 |
| 2019-01-03 |
| 2019-01-06 |
±------------------+

Result table:
±-------------±-------------±-------------+
| period_state | start date | end date |
±-------------±-------------±-------------+
| succeeded | 2019-01-01 | 2019-01-03 |
| failed | 2019-01-04 | 2019-01-05 |
| succeeded | 2019-01-06 | 2019-01-06 |
±-------------±-------------±-------------+

结果忽略了 2018 年的记录,因为我们只关心从 2019-01-01 到 2019-12-31 的记录
从 2019-01-01 到 2019-01-03 所有任务成功,系统状态为 “succeeded”。
从 2019-01-04 到 2019-01-05 所有任务失败,系统状态为 “failed”。
从 2019-01-06 到 2019-01-06 所有任务成功,系统状态为 “succeeded”。

思路:
看到这道题,就有一个想法,我可以将每天的数据查询出来,然后进行排序,把状态相同的数据进行合并,找到开始和结束时间
不过遇到了难点,就是怎么合并数据,我的想法是从第一条开始,一条一条做标记,如果状态变化,标记就修改,这样同一种标记的就可以合并
不过,还是不知道怎么做
最后看了题解,可以使用自定义的变量
set @prev = null;
set @tmp = 0;
但是不能直接这么用,因为leetcode只认语句sql,如果像上面这么set,得多条sql
然后还是题解,把设置变量的代码写到查询中,组成一个关联表
答案:
select period_state ,min(date) start_date,max(date) end_date
from
(select date,period_state,
if(@prev = period_state ,@tmp := @tmp, @tmp := @tmp + 1) as rank,
@prev := period_state as prev
from
(select * from (
select ‘succeeded’ period_state,success_date date from Succeeded where success_date between ‘2019-01-01’ and ‘2019-12-31’
union all
select ‘failed’ period_state,fail_date date from Failed where fail_date between ‘2019-01-01’ and ‘2019-12-31’) t0
order by date
)t1,(select @prev := null,@tmp := 0) as init)t2
group by rank

解剖:
//查询每一天数据,按时间排序
select * from (
select ‘succeeded’ period_state,success_date date from Succeeded where success_date between ‘2019-01-01’ and ‘2019-12-31’
union all
select ‘failed’ period_state,fail_date date from Failed where fail_date between ‘2019-01-01’ and ‘2019-12-31’) t0
order by date
//将查出来的数据,进行标记
select date,period_state,
if(@prev = period_state ,@tmp := @tmp, @tmp := @tmp + 1) as rank,
@prev := period_state as prev
from
(select * from (
select ‘succeeded’ period_state,success_date date from Succeeded where success_date between ‘2019-01-01’ and ‘2019-12-31’
union all
select ‘failed’ period_state,fail_date date from Failed where fail_date between ‘2019-01-01’ and ‘2019-12-31’) t0
order by date
)t1,(select @prev := null,@tmp := 0) as init
//通过标记,进行分组
select period_state ,min(date) start_date,max(date) end_date
from
(select date,period_state,
if(@prev = period_state ,@tmp := @tmp, @tmp := @tmp + 1) as rank,
@prev := period_state as prev
from
(select * from (
select ‘succeeded’ period_state,success_date date from Succeeded where success_date between ‘2019-01-01’ and ‘2019-12-31’
union all
select ‘failed’ period_state,fail_date date from Failed where fail_date between ‘2019-01-01’ and ‘2019-12-31’) t0
order by date
)t1,(select @prev := null,@tmp := 0) as init)t2
group by rank

发布了127 篇原创文章 · 获赞 16 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_33321609/article/details/102728863