Se entendi seus requisitos corretamente, se este gráfico representa a atividade do usuário:
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
...
Você quer saber que 02:00 é a hora do dia com a maior média de atividade (uma linha com 7
x
) e 12/4 foi o dia mais ativo (uma coluna com 10 x
). Observe que isso não implica que 02:00 de 12/4 foi a hora mais ativa de todos os tempos, como você pode ver no exemplo. Se não é isso que você deseja, por favor, esclareça com exemplos concretos de entrada e resultado desejado. Fazemos algumas suposições:
- Um registro de atividade pode começar em uma data e terminar na próxima. Por exemplo:on-line
2013-12-02 23:35
, off-line2013-12-03 00:13
. - Nenhum registro de atividade tem duração superior a 23 horas ou o número desses registros é insignificante.
E precisamos definir o que significa 'atividade'. Escolhi os critérios que eram mais fáceis de calcular em cada caso. Ambos podem ser mais precisos, se necessário, ao custo de ter consultas mais complexas.
- A hora mais ativa do dia será a hora em que mais registros de atividade se sobrepõem. Observe que, se um usuário iniciar e parar mais de uma vez durante a hora, ele será contado mais de uma vez.
- O dia mais ativo será aquele para o qual havia mais usuários únicos ativos a qualquer hora do dia.
Para a hora mais ativa do dia, usaremos uma pequena mesa auxiliar com as 24 horas possíveis. Também pode ser gerado e unido em tempo real com as técnicas descritas em outras respostas.
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);
Em seguida, as seguintes consultas fornecem os resultados necessários:
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;