Si entendí correctamente sus requisitos, si este gráfico representa la actividad del usuario:
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
...
Quiere saber que las 02:00 es la hora del día con el promedio de actividad más alto (una fila con 7 x
), y 12/4 fue el día más activo (una columna con 10 x
). Tenga en cuenta que esto no implica que las 02:00 del 12/4 haya sido la hora más activa de la historia, como puede ver en el ejemplo. Si esto no es lo que desea, aclare con ejemplos concretos de entrada y resultado deseado.
Hacemos un par de suposiciones:
- Un registro de actividad puede comenzar en una fecha y finalizar en la siguiente. Por ejemplo:en línea
2013-12-02 23:35
, sin conexión2013-12-03 00:13
. - Ningún registro de actividad tiene una duración superior a 23 horas, o el número de tales registros es insignificante.
Y necesitamos definir qué significa 'actividad'. Elegí los criterios que eran más fáciles de calcular en cada caso. Ambos pueden hacerse más precisos si es necesario, a costa de tener consultas más complejas.
- La hora del día más activa será la hora con la que se superpongan más registros de actividad. Tenga en cuenta que si un usuario inicia y se detiene más de una vez durante la hora, se contará más de una vez.
- El día más activo será aquel en el que haya más usuarios únicos activos en cualquier momento del día.
Para los momentos más activos del día utilizaremos una pequeña mesa auxiliar que aguante las 24 horas posibles. También se puede generar y unir sobre la marcha con las técnicas descritas en otras respuestas.
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);
Luego, las siguientes consultas dan los resultados requeridos:
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;