查找连续出现的记录

Find records that occur for consecutive times

我需要查找所有大于 5 的记录,但从上次大于 5 的连续记录开始。请注意,我可以有不同的 FormID。

    FormID   Value  LogDate
    Form1    6      10/12/19
    Form1    7      10/12/19
    Form1    4      10/14/19
    Form1    8      10/20/19
    Form1    9      10/21/19

在上面的示例中,结果如下:

    FormID   Value  LogDate   row_num
    Form1    8      10/20/19  1
    Form1    9      10/21/19  2

因为我们有 2 条连续大于 5 的记录。

示例 2:

    FormID   Value  LogDate
    Form1    6      10/12/19
    Form1    7      10/12/19
    Form1    6      10/14/19
    Form1    3      10/20/19
    Form1    9      10/21/19

在上面的示例中,结果将是:

    FormID   Value  LogDate   row_num
    Form1    9      10/21/19  1

示例 3:

    FormID   Value  LogDate
    Form1    6      10/12/19
    Form1    7      10/12/19
    Form1    6      10/14/19
    Form1    3      10/20/19
    Form1    4      10/21/19

4小于5后不会显示任何值,最近没有大于5的记录。

示例 4:

    FormID   Value  LogDate
    Form2    6      10/12/19
    Form2    7      10/13/19
    Form1    6      10/12/19
    Form1    7      10/12/19
    Form1    6      10/14/19
    Form1    3      10/15/19
    Form1    6      10/15/19
    Form1    2      10/20/19

在这种情况下,我们应该看到以下内容:

    FormID   Value  LogDate   row_num
    Form2    6      10/12/19  1
    Form2    7      10/13/19  2

Form1 没有任何数据,因为没有数据,因为自从最近一次的值为 2 之后,它已经超过 5。

下面是一个入门示例脚本

   DECLARE @table1 TABLE
  (
   FormID VARCHAR(50), 
   [Value] INT, 
   LogDate DATETIME
  )

  INSERT INTO @table1
  VALUES 
  ('Form2',6,'10/12/19'),
  ('Form2',7,'10/13/19'),
  ('Form1',6,'10/12/19')  ,
  ('Form1',7, '10/12/19') ,
  ('Form1',6,'10/14/19') ,
  ('Form1',3,'10/15/19'),
  ('Form1', 4, '10/21/19'),
  ('Form1',6, '10/21/19'),
  ('Form1', 6, '10/21/19'),
  ('Form1', 2, '10/25/19')

 select FormID, 
 Value, LogDate,
 Row_number()
 OVER(
        PARTITION BY FormID
        ORDER BY LogDate) AS row_num
 from @table1

这看起来像是一个缺口和孤岛问题。 Islands 表示值大于 5 的相邻记录,您想要除第一个以外的所有岛屿。

这是一种使用 window 函数的方法;逻辑是将每个岛的开始标识为从低于 5 的值到高于 5 的值的过渡:

select formid, value, logdate
from (
    select t.*, 
        sum(case when value > 5 and (lag_value <= 5 or lag_value is null) then 1 else 0 end)
            over(partition by formid order by logdate) flag
    from (
        select t.*, 
            lag(value) over(partition by formid order by logdate) lag_value
        from mytable t
    ) t
) t
where value > 5 and flag > 1