Wenn ich Ihre Anforderungen richtig verstanden habe, stellt dieses Diagramm die Benutzeraktivität dar:
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
...
Sie möchten wissen, dass 02:00 die Tageszeit mit der höchsten durchschnittlichen Aktivität ist (eine Zeile mit 7 x
) und der 4.12. war der aktivste Tag (eine Spalte mit 10 x
). Beachten Sie, dass dies nicht bedeutet, dass 02:00 Uhr am 4.12. die aktivste Stunde aller Zeiten war, wie Sie im Beispiel sehen können. Wenn Sie dies nicht möchten, erläutern Sie dies bitte anhand konkreter Beispiele für die Eingabe und das gewünschte Ergebnis.
Wir machen ein paar Annahmen:
- Eine Aktivitätsaufzeichnung kann an einem Datum beginnen und am nächsten enden. Zum Beispiel:online
2013-12-02 23:35
, offline2013-12-03 00:13
. - Keine Aktivitätsaufzeichnung hat eine Dauer von mehr als 23 Stunden oder die Anzahl solcher Aufzeichnungen ist vernachlässigbar.
Und wir müssen definieren, was „Aktivität“ bedeutet. Ich habe jeweils die Kriterien ausgewählt, die einfacher zu berechnen waren. Beide können bei Bedarf genauer gemacht werden, auf Kosten komplexerer Abfragen.
- Die aktivste Tageszeit ist die Stunde, mit der sich mehr Aktivitätsaufzeichnungen überschneiden. Beachten Sie, dass ein Benutzer, der während einer Stunde mehr als einmal startet und stoppt, mehr als einmal gezählt wird.
- Der aktivste Tag ist der Tag, an dem zu jeder Tageszeit mehr Unique User aktiv waren.
Für die aktivste Tageszeit verwenden wir eine kleine Hilfstabelle, die die 24 möglichen Stunden enthält. Es kann auch im Handumdrehen mit den in anderen Antworten beschriebenen Techniken generiert und verbunden werden.
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);
Dann liefern die folgenden Abfragen die gewünschten Ergebnisse:
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;