【问题标题】:Find records that occur for consecutive times查找连续出现的记录
【发布时间】:2021-02-20 05:08:20
【问题描述】:

我需要查找所有大于 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

小于5的值4之后不会显示任何值,最近没有大于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

【问题讨论】:

    标签: sql sql-server tsql datetime gaps-and-islands


    【解决方案1】:

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

    这是一种使用窗口函数的方法;逻辑是将每个岛的起点识别为从低于 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
    

    【讨论】:

    • 谢谢,但我发现这似乎不起作用。请看一下我更新的最新插入语句。我们不应该看到 Form1 的任何值,但我们看到了。 Form2 也应该显示结果。提前谢谢你
    • @NatePet:新数据集/结果与原始数据集/结果根本不一致。该查询适用于您的原始版本的问题。如果您有一个新问题,您应该将其作为一个新问题而不是使现有答案无效...
    • 感谢您的帮助。我创建了以下内容:stackoverflow.com/questions/64753746/… 新问题。我们将不胜感激。
    猜你喜欢
    • 2018-12-01
    • 2019-02-16
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多