Mysql
 sql >> Database >  >> RDS >> Mysql

ora del giorno più attiva in base all'ora di inizio e di fine

Se ho capito bene le tue esigenze, se questo grafico rappresenta l'attività dell'utente:

       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
   ...

Vuoi sapere che 02:00 è l'ora del giorno con l'attività media più alta (una riga con 7 x ) e 12/4 era il giorno più attivo (una colonna con 10 x ). Nota che questo non implica che le 02:00 del 4/12 fosse l'ora più attiva in assoluto, come puoi vedere nell'esempio. Se questo non è ciò che desideri, chiarisci con esempi concreti di input e risultato desiderato.

Facciamo un paio di ipotesi:

  • Un record di attività può iniziare in una data e terminare in quella successiva. Ad esempio:online 2013-12-02 23:35 , offline 2013-12-03 00:13 .
  • Nessun record di attività ha una durata superiore a 23 ore o il numero di tali record è trascurabile.

E dobbiamo definire cosa significa 'attività'. Ho scelto i criteri che erano più facili da calcolare in ogni caso. Entrambi possono essere resi più accurati se necessario, a costo di avere query più complesse.

  • L'ora del giorno più attiva sarà l'ora con cui si sovrappongono più record di attività. Tieni presente che se un utente si avvia e si ferma più di una volta durante l'ora, verrà conteggiato più di una volta.
  • Il giorno più attivo sarà quello per il quale c'erano più utenti unici attivi in ​​qualsiasi momento della giornata.

Per l'ora più attiva della giornata utilizzeremo una piccola tabella ausiliaria che contiene le 24 ore possibili. Può anche essere generato e unito al volo con le tecniche descritte in altre risposte.

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);

Quindi le seguenti query danno i risultati richiesti:

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;