sql >> Base de Datos >  >> RDS >> Mysql

hora del día más activa en función de la hora de inicio y finalización

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ón 2013-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;