Grupowanie rekordów na podstawie przedziałów czasu

12

Mam tabelę z następującym schematem i muszę zdefiniować zapytanie, które może grupować dane na podstawie przedziałów czasu ( np. Rekordów na minutę ), a następnie podać sumę zmian w SnapShotValue od poprzedniej grupy. Obecnie SnapShotValue zawsze zwiększa, więc potrzebuję tylko sumy różnic. Czy ktoś może pomóc z zapytaniem SQL Server T-SQL, który może to zrobić? Jestem otwarty na zmianę schematu, ale właśnie to mam.

Schemat

CaptureTime   (datetime)
SnapShotValue (int)

Przykładowe dane

1 Jan 2012 00:00:00,   100
1 Jan 2012 00:00:30,   125
1 Jan 2012 00:01:00,   200
1 Jan 2012 00:01:30,   300
1 Jan 2012 00:02:15,   400
1 Jan 2012 00:02:30,   425
1 Jan 2012 00:02:59,   500

Pożądany wynik zapytania

1 Jan 2012 00:01:00,   225 -- Sum of all captured data changes up to the 1 minute mark
1 Jan 2012 00:02:00,   500 -- Sum of all captured data changes up to the 2 minute mark
1 Jan 2012 00:03:00,   125 -- Sum of all captured data changes up to the 3 minute mark
JoeGeeky
źródło

Odpowiedzi:

17
select dateadd(minute, 1+datediff(minute, 0, CaptureTime), 0),
       sum(SnapShotValue)
from YourTable
group by dateadd(minute, 1+datediff(minute, 0, CaptureTime), 0)

Dane SE

datediff(minute, 0, CaptureTime)daje liczbę minut od 1900-01-01T00:00:00.

dateadd(minute, 1+datediff(minute, 0, CaptureTime), 0)dodaje liczbę minut od zakończenia 1900-01-01T00:00:00do daty i godziny, która 1900-01-01T00:00:00ma tylko minuty.

1+Jest tam dlatego, że chciał następną minutę.

Aby zrobić to samo z 5-minutowym interwałem, musisz wykonać kilka obliczeń. Dzielenie minut 5zi mnożenie przez 5daje minuty zaokrąglone w dół z dokładnością do 5 minut. Działa to, ponieważ wynikiem podziału liczb całkowitych w programie SQL Server jest liczba całkowita.

dateadd(minute, 5 + (datediff(minute, 0, CaptureTime) / 5) * 5, 0)
Mikael Eriksson
źródło
Zapewniło to dobre ramy dla odpowiedzi, ale wciąż mam problem z zrozumieniem, jak to działa. Kiedy próbowałem zmienić przesunięcie z przedziału 1 minuty na przedział 5 minut, nadal otrzymuję przedział 1 minuty, a cały wynik zaczyna się w innym punkcie początkowym. Jest to bardzo prawdopodobne, ponieważ nie rozumiem, jak to działa. Czy możesz podać jeszcze jedną próbkę z przedziałem innym niż 1 minuta? Dzięki ...
JoeGeeky
0

Jestem trochę zdezorientowany trzecim przykładem, czy to ma być 1325? W oparciu o wymagania dotyczące przechwytywania sumy wartości migawek poniższe zapytanie powinno uzyskać to, czego szukasz.

select dateadd(minute,1,convert(varchar(20),capturetime)), sum(snapshotvalue)
from snapshotdata sd
group by dateadd(minute,1,convert(varchar(20),capturetime))
WT_W
źródło
0

Poniżej znajduje się tłumaczenie zaakceptowanej odpowiedzi na PostgreSQL (jako datę bazową wybrałem 1 stycznia 2000 r. Zmień ją na wcześniejszą, jeśli Twoje dane są starsze):

SELECT 
  TIMESTAMP '2000-01-01 00:00:00' + 1 + DATE_PART('minute', CaptureTime - TIMESTAMP '2000-01-01 00:00:00') * INTERVAL '1 minute' 
  , SUM(SnapShotValue)
FROM table_name
GROUP BY TIMESTAMP '2000-01-01 00:00:00' + 1 + DATE_PART('minute', CaptureTime - TIMESTAMP '2000-01-01 00:00:00') * INTERVAL '1 minute' 
ORDER BY TIMESTAMP '2000-01-01 00:00:00' + 1 + DATE_PART('minute', CaptureTime - TIMESTAMP '2000-01-01 00:00:00') * INTERVAL '1 minute' 
LoMaPh
źródło