SQL Server:使用Lead连接符合条件的下一条记录

时间:2019-10-28 15:51:30

标签: sql sql-server

在某些情况下,我对lead()函数的用法有疑问。

假设我有一张桌子,如下所示:

    ----------------------------------
    id   |     time   |   condition  |
    1    |   12:00:00 |      fail    | 
    2    |   12:10:00 |      fail    |
    3    |   12:15:00 |     success  |
    4    |   12:20:00 |     success  | 

我想要一个包含一列的表,该列告诉我下一次成功的时间,并排除之间的所有失败记录。因此,就像

    ---------------------------------------------------
    id   |     time   |   condition  |   next_success |
    1    |   12:00:00 |      fail    |     12:15:00   |
    3    |   12:15:00 |     success  |     12:20:00   |
    4    |   12:20:00 |     success  |       null     |

我知道我可能可以使用lead()函数,但是最接近的是

select *, lead(time, 1) over (partition by condition order by time) as next_time from table 

这不是我想要的,因为我不仅想将失败或成功归类,还希望每条记录都紧跟着下一次成功的时间

希望有人可以提出一些解决方案的想法!

谢谢

2 个答案:

答案 0 :(得分:1)

使用CTE过滤行,并使用子查询返回下一次成功的行:

with cte as (
  select *, lag(condition, 1) over (order by time) as prev_condition
  from tablename
)
select c.id, c.time, c.condition,
  (select min(time) from cte where time > c.time and condition = 'success') as next_success
from cte c
where coalesce(c.prev_condition, '') <> 'fail' or c.condition <> 'fail' 

请参见demo
结果:

> id | time     | condition | next_success
> -: | :------- | :-------- | :-----------
>  1 | 12:00:00 | fail      | 12:15:00    
>  3 | 12:15:00 | success   | 12:20:00    
>  4 | 12:20:00 | success   | null

答案 1 :(得分:0)

为此,我将仅使用窗口函数。

select id, time, condition, next_success_time
from (select id, time, condition,
             min(case when condition = 'success' then time end) over (order by time rows between 1 following and unbounded following) as next_success_time,
             lead(condition) over (order by time) as next_condition
      from t
     ) t
where not (next_condition = 'fail' and condition = 'fail')