+--------------+---------+
| 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)。即如果任务失败了,就是失败状态的起止日期,如果任务成功了,就是成功状态的起止日期。
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"。
select fail_date date,'failed' state from Failed
union all
select success_date date,'succeeded' state from Succeeded
2018-12-28 failed
2018-12-29 failed
2019-01-04 failed
2019-01-05 failed
2018-12-30 succeeded
2018-12-31 succeeded
2019-01-01 succeeded
2019-01-02 succeeded
2019-01-03 succeeded
2019-01-06 succeeded
SELECT *,
SUBDATE(date,INTERVAL RANK() over (PARTITION by state ORDER BY date) day) ref
from
(select fail_date date,'failed' state from Failed
union all
select success_date date,'succeeded' state from Succeeded) a
WHERE date BETWEEN '2019-01-01' and '2019-12-31')
2019-01-04 failed 2019-01-03
2019-01-05 failed 2019-01-03
2019-01-01 succeeded 2018-12-31
2019-01-02 succeeded 2018-12-31
2019-01-03 succeeded 2018-12-31
2019-01-06 succeeded 2019-01-02
SELECT state period_state,
min(date) start_date,
max(date) end_date
from
(SELECT *, SUBDATE(date,INTERVAL RANK() over (PARTITION by state ORDER BY date) day) ref
from
(select fail_date date,'failed' state from Failed
union all
select success_date date,'succeeded' state from Succeeded
ORDER BY date) a
WHERE date BETWEEN '2019-01-01' and '2019-12-31') b
GROUP BY state, ref
ORDER BY start_date;