自学内容网 自学内容网

1225. 报告系统状态的连续日期 - 力扣(LeetCode)

目录

1. 力扣链接

2. 题目

3. 分析

4. 代码实现

5. 代码验证

6. 总结


1. 力扣链接

1225. 报告系统状态的连续日期 - 力扣(LeetCode)

2. 题目

表:Failed

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| fail_date    | date    |
+--------------+---------+
该表主键为 fail_date (具有唯一值的列)。
该表包含失败任务的天数.

表: Succeeded

+--------------+---------+
| Column Name  | Type    |
+--------------+---------+
| success_date | date    |
+--------------+---------+
该表主键为 success_date (具有唯一值的列)。
该表包含成功任务的天数.

系统 每天 运行一个任务。每个任务都独立于先前的任务。任务的状态可以是失败或是成功。

编写解决方案找出 2019-01-01 到 2019-12-31 期间任务连续同状态 period_state 的起止日期(start_date 和 end_date)。即如果任务失败了,就是失败状态的起止日期,如果任务成功了,就是成功状态的起止日期。

最后结果按照起始日期 start_date 排序

返回结果样例如下所示:

示例 1:

输入:
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        |
+-------------------+
输出:
+--------------+--------------+--------------+
| 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"。
-- 建表语句
Create table If Not Exists Failed (fail_date date);
Create table If Not Exists Succeeded (success_date date);
Truncate table Failed;
insert into Failed (fail_date) values ('2018-12-28');
insert into Failed (fail_date) values ('2018-12-29');
insert into Failed (fail_date) values ('2019-01-04');
insert into Failed (fail_date) values ('2019-01-05');
Truncate table Succeeded;
insert into Succeeded (success_date) values ('2018-12-30');
insert into Succeeded (success_date) values ('2018-12-31');
insert into Succeeded (success_date) values ('2019-01-01');
insert into Succeeded (success_date) values ('2019-01-02');
insert into Succeeded (success_date) values ('2019-01-03');
insert into Succeeded (success_date) values ('2019-01-06');

3. 分析

  1. 确定状态:首先,我们需要增加状态列确定每一天的状态。如果某一天在Succeeded表中,则状态为succeeded;如果在Failed表中,则状态为failed

  2. 合并日期:我们需要将FailedSucceeded两个表中的日期合并到一个单一的日期列表中

  3. 过滤日期范围:由于我们只关心2019年1月1日到2019年12月31日的记录,我们需要过滤掉这个范围之外的日期

  4. 确定等差数列一:我们按照时间进行排序,作为等差数列一

  5. 确定等差数列二:我们按照状态分组,对时间进行排序,作为等差数列二

  6. 确定连续:使用等差数列一减去等差数列二,差值相同则为同状态连续

  7. 确定周期:对于每个状态周期,我们需要确定其起始日期和结束日期。起始日期是状态连续开始的日期也就是分组后的最小日期,结束日期是状态连续结束的日期也就是分组后的最大日期

  8. 排序结果:最后,我们需要按照起始日期对结果进行排序

4. 代码实现

with t1 as(
    select
        'succeeded' period_state,
        success_date `date`
    from Succeeded
    union
    select
        'failed' period_state,
        fail_date `date`
    from Failed
),t2 as(
    select 
        *,
        row_number() over(order by `date`)
        -
        row_number() over(partition by period_state order by `date`) diff
    from t1 where `date` between '2019-01-01' and '2019-12-31'
)select 
    period_state,
    min(date) start_date,
    max(date) end_date 
from t2 
group by period_state,diff
order by start_date;

5. 代码验证

6. 总结

  • CTE (Common Table Expressions): 用于定义临时结果集,使复杂的查询更加清晰和易于管理。

  • UNION: 合并两个或多个SELECT语句的结果集,但去除重复的行。

  • ROW_NUMBER(): 窗口函数,用于为每个分区内的行分配一个唯一的序号。

  • PARTITION BY: 与窗口函数一起使用,将数据集划分为多个分区,每个分区独立进行计算。

  • ORDER BY: 在窗口函数中定义行的排序方式,确保序号分配的顺序。

  • GROUP BY: 将结果集的行分组,以便对每个组执行聚合函数。

  • MIN() and MAX(): 聚合函数,用于找出每个分组中的最小值和最大值。

  • ORDER BY: 对最终结果进行排序,确保输出的顺序性。

  • STRING ALIASING: 使用反引号为列名或表达式指定别名,特别是当列名包含特殊字符或空格时。


原文地址:https://blog.csdn.net/qq_58114907/article/details/144696593

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!