2009-12-10 12 views
7

Zasadniczo chcę agregować niektóre wartości w tabeli zgodnie z przedziałem czasowym.Dane zagregowane według zakresu czasowego w MySQL

Co mogę zrobić, to biorę migawek systemu co 15 minut, a ja chcę być w stanie wyciągnąć jakiś wykres w długim okresie. Ponieważ wykresy stają się naprawdę mylące, jeśli pokazane jest zbyt wiele punktów (poza bardzo powolnym renderowaniem), chcę zmniejszyć liczbę punktów, agregując wiele punktów w jeden punkt przez uśrednienie ich.

W tym celu musiałbym być w stanie grupować według wiader, które mogą być zdefiniowane przeze mnie (codziennie, co tydzień, co miesiąc, co rok, ...), ale jak dotąd wszystkie moje eksperymenty nie przynosiły szczęścia.

Czy jest jakiś trik można zastosować, aby to zrobić?

Odpowiedz

10

Miałem podobny pytanie: collating-stats-into-time-chunks i miał on odpowiedział bardzo dobrze. W istocie, odpowiedź brzmiała:

Być może można użyć funkcji DATE_FORMAT() i grupowanie. Oto przykład, mam nadzieję, że dostosujesz się do swoich konkretnych potrzeb.

SELECT 
    DATE_FORMAT(time, "%H:%i"), 
    SUM(bytesIn), 
    SUM(bytesOut) 
FROM 
    stats 
WHERE 
    time BETWEEN <start> AND <end> 
GROUP BY 
    DATE_FORMAT(time, "%H:%i") 

Jeśli okno czasowe obejmuje więcej niż jeden dzień i użyć przykładowy format, dane z poszczególnych dni będą agregowane do wiadra „godzina-of-day”. Jeśli surowe dane nie mieszczą się dokładnie w ciągu godziny, możesz je wygładzić, używając "% H: 00".

Dziękuję firmie Martin Clayton za udzieloną mi odpowiedź.

+0

Czy tej skali? Mój problem polega na tym, że po roku przyniesie to kilka milionów zgłoszeń. – cdecker

+1

Nie rozumiem, dlaczego by tego nie zrobił. Oczywiście konwersja dowolnego czasu jest powolna, ale większość czasu zostanie poświęcona na agregację samych danych, co jest nieuniknione w twoim przypadku. – cmroanirgo

2

Łatwo obciąć razy na ostatnie 15 minut (na przykład), robiąc coś takiego:

SELECT dateadd(minute, datediff(minute, '20000101', yourDateTimeField)/15 * 15, '20000101') AS the15minuteBlock, COUNT(*) as Cnt 
FROM yourTable 
GROUP BY dateadd(minute, datediff(minute, '20000101', yourDateTimeField)/15 * 15, '20000101'); 

używają podobnych metod ścinania do grupy przez godzinę, tydzień, cokolwiek.

Zawsze można owinąć go w instrukcji CASE, aby obsłużyć wiele sposobów, za pomocą:

GROUP BY CASE @option WHEN 'week' THEN dateadd(week, ..... 
Powiązane problemy