Jeśli dobrze zrozumiałem Twoje wymagania, jeśli ten wykres przedstawia aktywność użytkownika:
Day
12/1 12/2 12/3 12/4 ...
Hour 0 xx x x xx
1 x xx xx
2 xxx x x xx
3 x x
4 x x
5 x x
6 x
...
Chcesz wiedzieć, że 02:00 to pora dnia o największej średniej aktywności (wiersz z 7 x
), a 12/4 był najbardziej aktywnym dniem (kolumna z 10 x
). Zauważ, że nie oznacza to, że 02:00 z 12/4 była najbardziej aktywną godziną w historii, jak widać w przykładzie. Jeśli nie tego chcesz, wyjaśnij, podając konkretne przykłady danych wejściowych i pożądanego rezultatu.
Przyjmujemy kilka założeń:
- Rekord aktywności może rozpocząć się w jednym dniu i zakończyć w następnym. Na przykład:online
2013-12-02 23:35
, offline2013-12-03 00:13
. - Żaden rekord aktywności nie trwa dłużej niż 23 godziny lub liczba takich rekordów jest znikoma.
I musimy zdefiniować, co oznacza „aktywność”. W każdym przypadku wybrałem kryteria, które były łatwiejsze do obliczenia. Oba mogą być w razie potrzeby dokładniejsze, kosztem bardziej złożonych zapytań.
- Najbardziej aktywną porą dnia będzie godzina, na którą nakłada się więcej rekordów aktywności. Pamiętaj, że jeśli użytkownik zacznie i zatrzyma się więcej niż raz w ciągu godziny, zostanie to policzone więcej niż raz.
- Najbardziej aktywny dzień to ten, w którym było więcej unikalnych użytkowników aktywnych o dowolnej porze dnia.
Dla najbardziej aktywnej pory dnia użyjemy małego pomocniczego stolika na 24 możliwe godziny. Można go również generować i łączyć w locie za pomocą technik opisanych w innych odpowiedziach.
CREATE TABLE hour ( hour tinyint not null, primary key(hour) );
INSERT hour (hour)
VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
, (11), (12), (13), (14), (15), (16), (17), (18), (19), (20)
, (21), (22), (23);
Następnie następujące zapytania dają wymagane wyniki:
SELECT hour, count(*) AS activity
FROM steamonlineactivity, hour
WHERE ( hour BETWEEN hour(online) AND hour(offline)
OR hour(online) BETWEEN hour(offline) AND hour
OR hour(offline) BETWEEN hour AND hour(online) )
GROUP BY hour
ORDER BY activity DESC;
SELECT date, count(DISTINCT userID) AS activity
FROM (
SELECT userID, date(online) AS date
FROM steamonlineactivity
UNION
SELECT userID, date(offline) AS date
FROM steamonlineactivity
) AS x
GROUP BY date
ORDER BY activity DESC;