2010-10-21 16 views
6

ho i dati dei sensori in una tabella nella forma:derivata discreta in SQL

Time  Value 
10  100 
20  200 
36  330 
46  440 

vorrei tirare il cambiamento di valori per ogni periodo di tempo. Idealmente, mi piacerebbe ottenere:

Starttime Endtime Change 
10  20  100 
20  36  130 
36  46  110 

mie competenze SQL sono abbastanza rudimentali, quindi la mia inclinazione è di tirare tutti i dati ad uno script che elabora e quindi spingere di nuovo alla nuova tabella, ma Ho pensato di chiedere se ci fosse un modo intelligente per fare tutto questo nel database.

+0

Farebbe una domanda di intervista eccellente: banale da formulare ma non banale da risolvere. –

+0

+1 per il fatto che sei abbastanza intelligente da non farlo solo nel modo in cui già conosci e facendo la domanda. – Kuberchaun

risposta

1
Select a.Time as StartTime 
    , b.time as EndTime 
    , b.time-a.time as TimeChange 
    , b.value-a.value as ValueChange 
FROM YourTable a 
Left outer Join YourTable b ON b.time>a.time 
Left outer Join YourTable c ON c.time<b.time AND c.time > a.time 
Where c.time is null 
Order By a.time 
+0

Mi sembra un po 'inefficiente. Ha senso fare 2 join quando un join sarebbe sufficiente? Vedere questa risposta http://stackoverflow.com/questions/6299950/sql-difference-between-rows –

0

Prima di tutto, vorrei aggiungere una colonna id alla tabella in modo da avere qualcosa che aumenta in modo prevedibile da una riga all'altra.

Poi, vorrei provare la seguente query:

SELECT t1.Time AS 'Starttime', t2.Time AS 'Endtime', 
    (t2.Value - t1.Value) AS 'Change' 
FROM SensorData t1 
INNER JOIN SensorData t2 ON (t2.id - 1) = t1.id 
ORDER BY t1.Time ASC 

ho intenzione di creare una tabella di test per provare questo per me così io non so se funziona ancora, ma ne vale la pena un colpo!

Aggiornamento fisso con un problema minore (Il cambiamento è una parola protetta e ha dovuto essere citato), ma testato e funziona! Produce esattamente i risultati sopra definiti.

+0

Funzionerà solo se le righe sono inserite nell'ordine (di startTime), E nessuna riga verrà mai cancellata; l'eliminazione di una riga comporterà un gap, quindi t2.id - t1.id sarà> 1 – Andy

+0

In effetti, hai ragione, ma data la natura dei dati (cioè provenienti da un sensore) mi aspetto che le righe siano correttamente sequenziale e una riga cancellata sarebbe improbabile (credo) in quanto sarebbe effettivamente una lacuna nei dati. –

2
Select a.Time as StartTime, b.time as EndTime, b.time-a.time as TimeChange, b.value-a.value as ValueChange 
FROM YourTable a, YourTable b 
WHERE b.time = (Select MIN(c.time) FROM YourTable c WHERE c.time>a.time) 
+0

Testato questo sulla mia copia del tavolo e funziona anche. Mi piace l'aggiunta della modifica dell'ora e il cambio di valore :) –

+0

Vedi anche la mia altra risposta, evita la sottoquery. – Andy

0

funziona?

WITH T AS 
(
SELECT [Time] 
    , Value 
    , RN1 = ROW_NUMBER() OVER (ORDER BY [Time]) 
    , RN2 = ROW_NUMBER() OVER (ORDER BY [Time]) - 1 
FROM SensorData 
) 
SELECT 
    StartTime = ISNULL(t1.[time], t2.[time]) 
, EndTime = ISNULL(t2.[time], 0) 
, Change = t2.value - t1.value 

FROM T t1 
    LEFT OUTER JOIN 
     T t2 

ON t1.RN1 = t2.RN2 
+0

Funzionerebbe per SQL Server, ma ora mi rendo conto che non è codificato. –

Problemi correlati