2013-08-23 3 views
5

ho una tabella con la seguente strutturaGet differenza di tempo tra gruppo di record

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 

voglio calcolare la differenza di tempo totale per ogni ID contro Stato 2. Ad esempio ID 19 stati su Status 2 da 14 : Dalle 35 alle 14:50 (15 minuti), quindi dalle 14:22 alle 14:30 (8 minuti). Quindi l'ID totale 19 rimasto sullo Status 2 è di 23 minuti. (In entrambi i casi ho considerato il tempo minimo per lo stato 2 allo stato 1) Il problema è come posso includere unica differenza tra Stato dove sono diversi nel riga successiva.

Ad esempio escluderei il primo record nella tabella con lo stato 1 e selezionerei la seconda riga. Lo stesso vale per lo stato 2. Prenderò il tempo minimo, calcolerò la differenza e quindi li aggiungerò per più gruppi di stato rispetto a ciascun canale.

Ho provato a utilizzare CURSOR ma non riesco a farlo funzionare. Sono anche abbastanza fiducioso di poterlo realizzare in C# dopo aver ottenuto tutti i dati e poi averlo ripetuto. Ma mi chiedo solo se esiste un modo diretto per ottenere le informazioni senza un ciclo. Ho anche creato un SQL fiddle con dati, ma non riesco a farlo funzionare. Vengo dallo sfondo C# con le conoscenze di base di SQL. Sarei felice se qualcuno mi può aiutare.

+0

'14:35 A 14:50 (5 minuti)'? 5 minuti o 15 minuti? Dovresti rivedere la regola nella tua domanda e assicurarti che sia ciò che desideri perché è molto importante che le risposte siano in grado di aiutarti. –

+0

Non capisco cosa vuoi fare ... potresti forse elaborare un po 'di più? – Botis

+0

@KingKing, è stato un errore di battitura, grazie per averlo indicato. – user2711965

risposta

6

CTE (common table expressions) può essere utilizzato come una tabella temporanea specializzata. Ti consente (in questo caso) di creare dinamicamente un numero di riga che puoi successivamente creare un self join.

penso che siete alla ricerca di qualcosa di simile:

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

Grazie mille, questo sembra perfetto, vorrei poter invitarvi più volte. – user2711965

+1

Si noti che sto ordinando la prima query per ID e attività. Questo è il modo in cui sto stabilendo l'ordine delle righe. Questo deve essere stabilito perché è necessario sapere qual è la riga "successiva".La seconda parte della query è la ricorsione che unisce la riga corrente alla riga successiva – paqogomez

+1

Questa query conta una somma tra tutti i 'ActivityTime' dove' Status' = 2, ma la somma reale deve essere compresa tra la prima riga con 'Status = 2' e la prima riga che appare per la prima volta con 'Status = 1' – Fabio