查找连续出现的记录
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
我需要查找所有大于 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