zoukankan      html  css  js  c++  java
  • 1225. 报告系统状态的连续日期

    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     |
    +--------------+--------------+--------------+
    | present      | 2019-01-01   | 2019-01-03   |
    | missing      | 2019-01-04   | 2019-01-05   |
    | present      | 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"。


    我是这样想的:
    先按照日期递增的顺序把失败的和成功的天数连续查出来,sql如下:

       select date,period_state from (
       select fail_date as date,'failed' as period_state from failed
       where fail_date between '2019-01-01' and '2019-12-31'
       union all
       select success_date as date,'succeeded' as period_state from Succeeded
       where success_date between '2019-01-01' and '2019-12-31'
       ) t1 order by t1.date as
    

    然后按照连续天数的状态给个排名rank,连续的状态相同的rank一样,不一样的rank递增,
    sql如下:

    select date,period_state,
    if(@prev = period_state ,@tmp := @tmp, @tmp := @tmp + 1) as rank,
    @prev := period_state as prev from
    (select date,period_state from (
    	select fail_date as date,'failed' as period_state from failed
    	where fail_date between '2019-01-01' and '2019-12-31'
    	union all
    	select success_date as date,'succeeded' as period_state from Succeeded
    	where success_date between '2019-01-01' and '2019-12-31'
    	) t1 order by t1.date asc) t2,(select @prev := null,@tmp := 0) as init
    

    得到上述结果之后,再按照rank分组,把每一组的最大值和最小值分别作为start_date和end_date,
    完整的sql如下:

    select t3.period_state as period_state,min(date) as start_date,
    max(date) as 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 date,period_state from (
    	select fail_date as date,'failed' as period_state from failed
    	where fail_date between '2019-01-01' and '2019-12-31'
    	union all
    	select success_date as date,'succeeded' as period_state from Succeeded
    	where success_date between '2019-01-01' and '2019-12-31'
    	) t1 order by t1.date asc) t2,(select @prev := null,@tmp := 0) as init) t3
        group by rank
  • 相关阅读:
    java io 学习笔记(一)
    Centos中查看系统信息的常用命令
    arcgis影像批量裁剪代码
    VS2010中VC++目录和C/C++之间的区别。VC++ Directories和C/C++的区别。
    VS中为什么不同的项目类型属性查看和设置的界面不一样
    C++函数中返回引用和返回值的区别
    java中HashMap的keySet()和values()
    repoquery详解——linux查看包依赖关系的神器
    linux学习笔记
    log4j的AppenderLayout格式符
  • 原文地址:https://www.cnblogs.com/leeeee/p/11902026.html
Copyright © 2011-2022 走看看