我不确定如何标题这个问题,但我尽了最大努力......使用SQL Server 2016时,我遇到了一些小问题。
我有一个包含许多行的表,并且所有行都有一个时间戳列。根据列Lane_0(值0或1)的值,我需要从日期时间列中获取时间戳。
表格如下:
行组标有黄色。
基本上,该表用于跟踪某些内容何时开启或关闭。 1 =开,0 =关。我需要找到每个组关闭时间(值0)以及该组的最旧和最新时间戳。组是Lane_0中0的行集合。
从图片中我必须获得Row_num 7,8和9,然后从第7行的时间戳中减去第9行中的date_time以获得持续时间。最后,我需要在Row_num 7和9中选择date_time。
结果应如下所示:
最后一张照片显示第一组带有三个黄色标记。我需要一个可以从表1中选择所有有效组的视图或SQL查询。
答案 0 :(得分:1)
这是连续分组的标准技巧:
DECLARE @t TABLE
(
rn INT ,
dt DATETIME ,
ln INT
)
INSERT INTO @t
VALUES ( 5, GETDATE(), 1 ),
( 6, GETDATE(), 1 ),
( 7, GETDATE(), 0 ),
( 8, GETDATE(), 0 ),
( 9, DATEADD(ss, 15, GETDATE()), 0 ),
( 10, GETDATE(), 1 ),
( 11, GETDATE(), 1 ),
( 12, GETDATE(), 0 ),
( 13, DATEADD(ss, 6, GETDATE()), 0 ),
( 14, GETDATE(), 1 );
WITH cte
AS ( SELECT * ,
ROW_NUMBER() OVER ( ORDER BY rn )
- ROW_NUMBER() OVER ( ORDER BY ln, rn ) r
FROM @t
)
SELECT MIN(dt) ,
MAX(dt) ,
DATEDIFF(ss, MIN(dt), MAX(dt))
FROM cte
WHERE ln = 0
GROUP BY r
输出:
2017-01-09 15:47:31.560 2017-01-09 15:47:46.560 15
2017-01-09 15:47:31.560 2017-01-09 15:47:37.560 6
答案 1 :(得分:1)
你需要识别"岛屿"在数据中。一种方法使用行号的差异:
select lane_no, min(datetime), max(datetime), count(*),
datediff(second, min(datetime), max(datetime)) as dur_second,
datediff(second, min(datetime), max(datetime))/60.0 as dur_minute
from (select t.*,
row_number() over (partition by lane_no order by date_time) as seqnum_l,
row_number() over (order by date_time) as seqnum
from t
) t
where lane_no = 0
group by lane_no, (seqnum - seqnum_l);