leetcode 1225 报告系统状态的连续日期(postgresql)

需求

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

编写一个 SQL 查询 2019-01-01 到 2019-12-31 期间任务连续同状态 period_state 的起止日期(start_date 和 end_date)。即如果任务失败了,就是失败状态的起止日期,如果任务成功了,就是成功状态的起止日期。

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

输入

在这里插入图片描述

分析

– 对成功表,使用rank函数对其排序,并筛选出2019年的数据
– 窗口函数排序:
– row_number:1,2,3,4
– rank:1,2,2,4
– dense_rank:1,2,2,3
2.
– 拼接字符串,因为一个是date类型,一个是int类型,不能直接相减,这里将int类型拼接字符串,
– 再将其转换为interval类型,再将两者相减。得到 2018-12-31 00:00:00.000000
3.
– 对上一步的结果,对相减后的结果分组,因为时间是递增的,排序也是递增的。
– 如果时间是连续的,那么二者相减,得到的时间就是相同的,
– 使用这个时间进行分组,再求出组内最小值作为开始时间,最大值作为结束时间
4.
– 对失败表进行上面相同的操作
5.
– 合并两次查询的结果,并按照开始时间排序

输出

with t1 as (
-- 对成功表,使用rank函数对其排序,并筛选出2019年的数据
-- 窗口函数排序:
    -- row_number:1,2,3,4
    -- rank:1,2,2,4
    -- dense_rank:1,2,2,3
select * ,
   rank() over (order by success_date) as rn1
from succeeded
where success_date>='2019-01-01' and success_date<='2019-12-31'
),t2 as (
-- 拼接字符串,因为一个是date类型,一个是int类型,不能直接相减,这里将int类型拼接字符串,
    -- 再将其转换为interval类型,再将两者相减。得到 2018-12-31 00:00:00.000000
select *,success_date-(rn1||'day')::interval as rn2
from t1
),t3 as (
-- 对上一步的结果,对相减后的结果分组,因为时间是递增的,排序也是递增的。
    -- 如果时间是连续的,那么二者相减,得到的时间就是相同的,
    -- 使用这个时间进行分组,再求出组内最小值作为开始时间,最大值作为结束时间
select 'succeeded' as period_state,min(success_date) as start_date,max(success_date) as end_date
from t2
group by rn2
),t4 as (
-- 对失败表进行上面相同的操作
select *,
   fail_date-((rank() over (order by fail_date))||'day')::interval as rn3
from failed
where fail_date>='2019-01-01' and fail_date<='2019-12-31'
)
-- 合并两次查询的结果,并按照开始时间排序
select 'failed' as period_state,min(fail_date) as start_date,max(fail_date) as end_date
from t4
group by rn3
union all
select * from t3
order by start_date
;

在这里插入图片描述

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值