排除具有可能重复的连续数据的行

Gyu*_*l R 4 sql-server greatest-n-per-group

我有一个表格显示特定设备在给定时间戳的状态(0 - 损坏,1 - 实时):

device_owner   device_id    timestamp          status
owner1         device_1     2001-01-01 09:00   0    -- leave this
owner1         device_1     2001-01-01 09:05   0    -- exclude
owner1         device_1     2001-01-01 09:10   0    -- exclude
owner1         device_2     2001-01-01 09:15   0    -- leave this
owner1         device_1     2001-01-01 09:30   1    
owner1         device_2     2001-01-01 09:35   0    -- exclude
owner1         device_2     2001-01-01 09:45   1
owner1         device_1     2001-01-01 09:55   0    --leave this
owner1         device_1     2001-01-01 10:10   0    --exclude
owner1         device_1     2001-01-01 10:11   1    
Run Code Online (Sandbox Code Playgroud)

等等。

我需要排除连续的零状态,并保留日期时间最早的状态。(这样我就可以定义设备损坏和活动之间的日期时间差异。)

结果:

device_owner   device_id    timestamp          status
owner1         device_1     2001-01-01 09:00   0    
owner1         device_2     2001-01-01 09:15   0    
owner1         device_1     2001-01-01 09:30   1
owner1         device_2     2001-01-01 09:45   1
owner1         device_1     2001-01-01 09:55   0    
owner1         device_1     2001-01-01 10:11   1
Run Code Online (Sandbox Code Playgroud)

等等。

然后在我的进一步计算中,device_1 的总细分将在 09:00 和09: 30、09 : 55 和 10:11 之间,对于device_2 – 09:15—09:45。

DDL:

DECLARE @t TABLE
      (
          device_owner VARCHAR(10),
          device_id VARCHAR(10),
          timestamp DATETIME,
          status BIT
      );

INSERT @t ( device_owner, device_id, timestamp, status )
SELECT *
FROM   
( 
  VALUES ('owner1', 'device_1', '2001-01-01 09:00',   0),    -- leave this
         ('owner1', 'device_1', '2001-01-01 09:05',   0),    -- exclude
         ('owner1', 'device_1', '2001-01-01 09:10',   0),    -- exclude
         ('owner1', 'device_2', '2001-01-01 09:15',   0),    -- leave this
         ('owner1', 'device_1', '2001-01-01 09:30',   1),    
         ('owner1', 'device_2', '2001-01-01 09:35',   0),    -- exclude
         ('owner1', 'device_2', '2001-01-01 09:45',   1),
         ('owner1', 'device_1', '2001-01-01 09:55',   0),    --leave this
         ('owner1', 'device_1', '2001-01-01 10:10',   0),    --exclude
         ('owner1', 'device_1', '2001-01-01 10:11',   1)    
) AS x ( device_owner, device_id, timestamp, status );
Run Code Online (Sandbox Code Playgroud)

我很感激任何建议。

Sab*_*n B 5

这似乎类似于 Itzik Ben-Gan 对间隙和岛屿的解决方案

SELECT [device_owner], [device_id],MIN(timestamp) as timestamp,status

FROM
(
SELECT *
   ,diff = ROW_NUMBER()OVER(PARTITION BY device_owner,device_id ORDER BY timestamp ASC) 
         - ROW_NUMBER()OVER(PARTITION BY device_owner,device_id , status ORDER BY timestamp ASC) 
FROM @t
)A
--WhERE status = 0
GROUP BY [device_owner], [device_id],status , diff
ORDER BY timestamp
Run Code Online (Sandbox Code Playgroud)

它的输出:

device_owner    device_id   timestamp           status
owner1          device_1    01/01/2001 09:00:00 False
owner1          device_2    01/01/2001 09:15:00 False
owner1          device_1    01/01/2001 09:30:00 True
owner1          device_2    01/01/2001 09:45:00 True
owner1          device_1    01/01/2001 09:55:00 False
owner1          device_1    01/01/2001 10:11:00 True
Run Code Online (Sandbox Code Playgroud)

数据库小提琴