我有一个包含以下结构的表
ID ActivityTime Status
19 2013-08-23 14:52 1
19 2013-08-23 14:50 1
19 2013-08-23 14:45 2
19 2013-08-23 14:35 2
19 2013-08-23 14:32 1
19 2013-08-23 14:30 1
19 2013-08-23 14:25 2
19 2013-08-23 14:22 2
53 2013-08-23 14:59 1
53 2013-08-23 14:56 1
53 2013-08-23 14:57 1
53 2013-08-23 14:52 2
53 2013-08-23 14:50 2
53 2013-08-23 14:49 2
53 2013-08-23 14:18 2
53 2013-08-23 14:30 1
我想计算每个ID与状态2的总时差。例如,ID 19从14:35到14:50(15分钟),然后是14:22到14:30(8分钟)保持在状态2 )。因此状态2中的总ID 19为23分钟。 (在这两种情况下,我都认为状态2的最短时间为状态1) 问题我如何仅在下一行中包含不同状态之间的差异。
例如,我将排除表中第一条记录,状态为1,然后选择第二行。状态2的情况也是如此。我会选择最小时间,计算它们的差异,然后将它们添加到每个通道的多组状态。
我尝试过使用CURSOR但似乎无法使其正常工作。我也非常有信心在获得所有数据然后循环之后我可以在C#中实现这一点。但我只是想知道是否有一种直接的方式来获取没有循环的信息。我还创建了一个带有数据的SQL fiddle,但我似乎无法使其工作。我来自C#背景,具有SQL的基本知识。如果有人可以帮助我,我会很高兴的。
答案 0 :(得分:6)
CTE(common table expressions)可以像专门的临时表一样使用。它允许您(在这种情况下)动态创建一个行号,以后可以创建自联接。
我认为你正在寻找这样的东西:
--create temp table
select 19 as id,'2013-08-23 14:52' as activitytime,1 as status
into #temp
union all
select 19,'2013-08-23 14:50',1 union all
select 19,'2013-08-23 14:45',2 union all
select 19,'2013-08-23 14:35',2 union all
select 19,'2013-08-23 14:32',1 union all
select 19,'2013-08-23 14:30',1 union all
select 19,'2013-08-23 14:25',2 union all
select 19,'2013-08-23 14:22',2 union all
select 53,'2013-08-23 14:59',1 union all
select 53,'2013-08-23 14:56',1 union all
select 53,'2013-08-23 14:57',1 union all
select 53,'2013-08-23 14:52',2 union all
select 53,'2013-08-23 14:50',2 union all
select 53,'2013-08-23 14:49',2 union all
select 53,'2013-08-23 14:18',2 union all
select 53,'2013-08-23 14:30',1
--build cte table
;WITH cte
AS (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY id, activitytime) AS RowNum
FROM
#temp
)
--query cte table, self joining row 1 to row 2 to compare.
SELECT a.id, sum(DATEDIFF(minute,b.ActivityTIme,a.ActivityTime)) as TotalTime
FROM
cte AS A
LEFT OUTER JOIN cte AS B
ON A.RowNum = B.RowNum + 1 and a.id = b.id
where b.status = 2
group by a.id