【问题标题】:need to modify the query without using cross/outer apply需要修改查询而不使用交叉/外部应用
【发布时间】:2019-05-24 06:26:58
【问题描述】:
create table PrinterData(
    Dt DateTime not null,
    Status nvarchar(50) not null    
)

insert into PrinterData
values
('05.24.2019 00:00:00', 'READY'),
('05.24.2019 00:01:00', 'READY'),
('05.24.2019 00:02:00', 'NO PAPER'),
('05.24.2019 00:03:00', 'UNKNOWN'),
('05.24.2019 00:04:00', 'UNKNOWN'),
('05.24.2019 00:05:00', 'READY'),
('05.24.2019 00:06:00', 'READY'),
('05.24.2019 00:07:00', 'READY'),
('05.24.2019 00:08:00', 'NO PAPER'),
('05.24.2019 00:09:00', 'UNKNOWN'),
('05.24.2019 00:10:00', 'HAS PAPER'),
('05.24.2019 00:11:00', 'NO PAPER')

我需要知道READY状态和下一个READYHAS PAPER之间的时间间隔,除了UNKNOWN地位。 未知我需要跳过。 结果应如下所示:

这是我的查询,但我不喜欢使用交叉/外部应用。在性能和速度方面,我需要您的建议,如何修改此查询。

select a.Dt, a.Status, b.Dt as Dt_Next_Status, b.Status as Next_Status, DATEDIFF(SECOND, a.Dt, b.Dt) as Diff from PrinterData a
outer apply 
(
    select top 1  Dt, Status from PrinterData where Dt > a.Dt and Status not in ('UNKNOWN', 'NO PAPER') 
) b
where a.Status = 'NO PAPER' 

【问题讨论】:

    标签: sql sql-server tsql sql-server-2012


    【解决方案1】:

    使用lead()函数

    DEMO

    select *,datediff(SECOND,dt,nexttime) as diff from 
    (
    select *,lead(dt) over(order by dt) as nexttime,lead(status) over(order by dt) as nextstatus
    from PrinterData
    where Status<>'UNKNOWN'
    )A where status='NO PAPER'
    

    输出:

    Dt                  Status      nexttime            nextstatus  diff
    24/05/2019 00:02:00 NO PAPER    24/05/2019 00:05:00 READY       180
    24/05/2019 00:08:00 NO PAPER    24/05/2019 00:10:00 HAS PAPER   120
    24/05/2019 00:11:00 NO PAPER        
    

    【讨论】:

      【解决方案2】:

      您可以使用左连接和 row_number() 来做到这一点

      with cte as
      (
      select a.Dt, a.Status, b.Dt as Dt_Next_Status, b.Status as Next_Status,
      DATEDIFF(SECOND, a.Dt, b.Dt) as Diff,
      row_number()over(partition by a.DT order by b.Dt) rn
      from PrinterData a
      left join
      (
          select  Dt, Status from PrinterData where Status not in ('UNKNOWN', 'NO PAPER') 
      ) b on  b.Dt > a.Dt
      where a.Status = 'NO PAPER' 
      ) 
      select * from cte where rn=1
      

      demo in fiddle

      【讨论】:

        猜你喜欢
        • 2020-04-27
        • 2013-04-04
        • 1970-01-01
        • 1970-01-01
        • 2013-02-04
        • 1970-01-01
        • 2016-08-20
        • 1970-01-01
        • 2018-02-14
        相关资源
        最近更新 更多