Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

hora mais ativa do dia com base na hora de início e término


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-line 2013-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;