Group by

lunedì 04 luglio 2011 - 16.29

dompa72 Profilo | Senior Member

Un piccolo problema a cui non ho travato soluzione

Ho una tabella con due campi il primo string ed il secondo di tipo datetime (campionati ogni 10 secondi circa) con questi valori
Descrizione DataOperazione
Manutenzione 20/06/2011 00:00:01
Manutenzione 20/06/2011 00:00:10
Manutenzione 20/06/2011 00:00:23
Produzione 20/06/2011 00:00:25
Produzione 20/06/2011 00:00:36
Produzione 20/06/2011 00:00:45
Manutenzione 20/06/2011 00:00:55
Manutenzione 20/06/2011 00:01:05
Produzione 20/06/2011 00:01:16
Produzione 20/06/2011 00:01:26
Produzione 20/06/2011 00:01:35

Vorrei avere un risultato con la data minima e massima raggruppati per il primo campo, ma ad ogni differenza,
con questa query "Select Descrizione, Min(dataoperazione) as Data_Min, Max(DataOperazione) as Data_Max from Tabella Group by Descrizione" mi ritorna questo risultato (giusto ma non mi soddisfa)

Descrizione Data_min Data_Max
Manutenzione 20/06/2011 00:00:01 20/06/2011 00:01:05
Produzione 20/06/2011 00:00:25 20/06/2011 00:01:35

Purtroppo a me serve questo tipo di risultato, questo per fare delle differenze tra le due date e controllare quante ore per singola occorrenza (Descrizione) nell'arco del periodo selezionato

Descrizione Data_min Data_Max
Manutenzione 20/06/2011 00:00:01 20/06/2011 00:00:23
Produzione 20/06/2011 00:00:25 20/06/2011 00:00:45
Manutenzione 20/06/2011 00:00:55 20/06/2011 00:01:05
Produzione 20/06/2011 00:01:16 20/06/2011 00:01:35

Esiste un modo per avere questo tipo di risultato??? Oppure sono costretto a calcolarlo con una funzione ad hoc?

Grazie mille per l'aiuto

speedx Profilo | Junior Member

Se ti calcoli min e max con due query separate, ovviamente sempre selezionando la data, e poi fai la diffrenza....
Che ne dici?
//// Marcello C.

dompa72 Profilo | Senior Member

Purtroppo i dati sono campionati ogni 10 secondi circa per sempre, le ricerche sono per periodo da un range scelto dall'utente, il campo Descrizione e' popolato con altre 10 stringhe diverse. Non penso che sia questa la via giusta.
In questo momento risolvo in questo modo: carico i dati in una tabella momentanea e calcolo la differenza tra i record, purtroppo questo modo ha tempi lunghi ed a volte inaccettabili.
Esistera' un modo migliore? Sicuramente

Grazie a tutti

lbenaglia Profilo | Guru

>Esistera' un modo migliore? Sicuramente

Ciao,

Ti propongo una soluzione basata sulla funzione di ranking ROW_NUMBER() introdotta con SQL Server 2005 che Itzik utilizzò in un suo articolo su SQL Server Magazine.
La funzione ROW_NUMBER() restituisce un numero sequenziale di una riga all'interno di una partizione di un result set, impostando a 1 la prima riga di ogni partizione.
Ora, l'intento è quello di identificare le "sezioni" all'interno del tuo result set (complessivamente 4 sezioni).
Applicando due volte la funzione ROW_NUMBER() all'unica partizione esistente ma ordinando prima per DataOperazione e successivamente per Descrizione, DataOperazione ed eseguendo la differenza tra i due valori otterrai una costante per ogni sezione.
A questo punto la soluzione è banale: è sufficiente calcolare le date minime e massime raggruppando il tutto per Descrizione e Sezione:

USE tempdb; CREATE TABLE dbo.foo( Descrizione varchar(15) NOT NULL, DataOperazione datetime NOT NULL ); INSERT dbo.foo VALUES ('Manutenzione', '20110620 00:00:01') , ('Manutenzione', '20110620 00:00:10') , ('Manutenzione', '20110620 00:00:23') , ('Produzione', '20110620 00:00:25') , ('Produzione', '20110620 00:00:36') , ('Produzione', '20110620 00:00:45') , ('Manutenzione', '20110620 00:00:55') , ('Manutenzione', '20110620 00:01:05') , ('Produzione', '20110620 00:01:16') , ('Produzione', '20110620 00:01:26') , ('Produzione', '20110620 00:01:35'); WITH CTE_RANK(Descrizione, DataOperazione, Sezione) AS ( SELECT * , ROW_NUMBER() OVER (ORDER BY DataOperazione) - ROW_NUMBER() OVER (ORDER BY Descrizione, DataOperazione) FROM dbo.foo ) SELECT Descrizione , MIN(DataOperazione) AS Data_Min , MAX(DataOperazione) AS Data_Max FROM CTE_RANK GROUP BY Descrizione, Sezione ORDER BY Data_Min; /* Output: Descrizione Data_Min Data_Max --------------- ----------------------- ----------------------- Manutenzione 2011-06-20 00:00:01.000 2011-06-20 00:00:23.000 Produzione 2011-06-20 00:00:25.000 2011-06-20 00:00:45.000 Manutenzione 2011-06-20 00:00:55.000 2011-06-20 00:01:05.000 Produzione 2011-06-20 00:01:16.000 2011-06-20 00:01:35.000 (4 row(s) affected) */ DROP TABLE dbo.foo;

>Grazie a tutti
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

dompa72 Profilo | Senior Member

Grazie
non avrei mai risolto.

Ora devo adattarla sui miei dati

Grazie ancora
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5