连续获得条件

时间:2019-03-13 07:30:11

标签: sql sql-server tsql

有一个包含三列的表:

CREATE TABLE #t1 ( Id INT
                  ,VisitDate DATE
                  ,Counter INT)

AND测试数据:

INSERT INTO #t1 VALUES (1,'2019-01-01', 50)
INSERT INTO #t1 VALUES (2,'2019-01-02', 15)
INSERT INTO #t1 VALUES (3,'2019-01-03', 7)
INSERT INTO #t1 VALUES (4,'2019-01-04', 7)
INSERT INTO #t1 VALUES (5,'2019-01-05', 18)
INSERT INTO #t1 VALUES (6,'2019-01-06', 19)
INSERT INTO #t1 VALUES (7,'2019-01-07', 11)
INSERT INTO #t1 VALUES (8,'2019-01-08', 1)
INSERT INTO #t1 VALUES (9,'2019-01-09', 19)

需要找到连续三天或更长时间,其中Counter等于或大于十:

Id  VisitDate   Counter
5   2019-01-05  18
6   2019-01-06  19
7   2019-01-07  11

我的SELECT语句是

;WITH cte AS 
(
    SELECT *
    ,IIF(Counter > 10, 1,0) AS MoreThanTen
    FROM   #t1
), lag_lead_cte AS
(
    SELECT *
    ,LAG(MoreThanTen) OVER (ORDER BY VisitDate) AS LagShift
    ,(LAG(MoreThanTen) OVER (ORDER BY VisitDate) +  MoreThanTen ) AS LagMoreThanTen
    ,LEAD(MoreThanTen) OVER (ORDER BY VisitDate) AS LeadShift
    ,(LEAD(MoreThanTen) OVER (ORDER BY VisitDate) +  MoreThanTen ) AS LeadMoreThanTen
    FROM cte
)
 SELECT *
 FROM    lag_lead_cte
 WHERE   LagMoreThanTen = 2 OR LeadMoreThanTen = 2

但是结果并不完全一致

Id  VisitDate   Counter
1   2019-01-01  50
2   2019-01-02  15
5   2019-01-05  18
6   2019-01-06  19
7   2019-01-07  11

1 个答案:

答案 0 :(得分:1)

我认为,仅使用lead()lag()查看序列就可以最简单地解决这个问题:

select id, visitdate, counter
from (select t1.*,
             lag(counter, 2) over (order by visitdate) as counter_2p,
             lag(counter, 1) over (order by visitdate) as counter_1p,
             lead(counter, 1) over (order by visitdate) as counter_1l,
             lead(counter, 2) over (order by visitdate) as counter_2l
      from t1
     ) t1
where counter >= 10 and
      ((counter_2p >= 10 and counter_1p >= 10) or
       (counter_1p >= 10 and counter_1l >= 10) or
       (counter_1l >= 10 and counter_2l >= 10) 
      );