2013-08-23 238 views
5

我有一個表具有以下結構獲取的記錄

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 

我想要計算針對狀態2.每個ID例如ID 19停留在狀態2從14的總時間差組之間的時間差:35至14:50(15分鐘),然後14:22至14:30(8分鐘)。因此,狀態2上的總共ID 19爲23分鐘。 (在這兩種情況下,我認爲狀態2狀態1的最短時間) 問題是我怎麼只包括狀態,他們在下一行不同的差異。

例如,我會排除狀態1表中的第一條記錄,並選擇第二行。狀態2的情況也是如此。我會選擇最短時間,計算它們的差異,然後將它們添加到每個通道的多組狀態。

我試過使用CURSOR,但似乎無法使其工作。我也非常確信,在獲取所有數據並循環遍歷之後,我可以在C#中實現這一點。但我只是想知道是否有直接的方式來獲得沒有循環的信息。我還用數據創建了一個SQL fiddle,但我似乎無法使其工作。我來自C#背景,具有SQL的基本知識。如果有人能幫助我,我會很高興。

+0

'14:35要14:50(5分鐘)'? 5分鐘或15分鐘?你應該檢查你的問題中的規則,並確保它是你想要的,因爲這對於答案能夠幫助你是非常重要的。 –

+0

我不太明白你想要做什麼..你可能會詳細說明一點嗎? – Botis

+0

@KingKing,這是一個錯字,感謝您指出了這一點。 – user2711965

回答

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 
+1

非常感謝,這看起來很完美,我希望我可以upvote你多次。 – user2711965

+1

請注意,我按ID和活動時間排序了第一個查詢。這是我如何建立行順序。這需要建立,因爲你需要知道「下一個」行是什麼。查詢的第二部分是將當前行連接到下一行的遞歸 – paqogomez

+1

該查詢計算所有'ActivityTime'之間'Status'= 2,但實際總和必須介於第一行和'Status = 2'之間的總和並且下一個第一個出現在'Status = 1'的行中 – Fabio