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

MySQL Conte dati per gli ultimi 7 giorni

MySQL non ha funzionalità ricorsive, quindi ti resta l'utilizzo del trucco della tabella NUMBERS -

  1. Crea una tabella che contenga solo numeri incrementali - facile da fare usando un auto_increment:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. Compila la tabella utilizzando:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...per tutti i valori di cui hai bisogno.

  3. Usa DATE_ADD per costruire un elenco di date, aumentando i giorni in base al valore NUMBERS.id. Sostituisci "01-01-2010" e "02-01-2010" con le rispettive date di inizio e fine (ma usa lo stesso formato, AAAA-MM-GG HH:MM:SS). In questo esempio, ho sottratto il valore NUMBERS.id da CURRENT_DATE per ottenere un elenco di valori di data sequenziali per l'ultima settimana -

    SELECT x.dt
      FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
              FROM numbers n
             WHERE n.id <= 7 ) x
    
  4. LEFT UNISCITI alla tua tabella di dati in base alla parte data/ora.

       SELECT x.dt,
               COUNT(v.aid) AS num
         FROM (SELECT DATE_SUB(CURRENT_DATE, INTERVAL (n.id - 1) DAY) AS dt
                 FROM numbers n
                WHERE n.id <= 7 ) x
    LEFT JOIN VOTES v ON DATE(FROM_UNIXTIME(v.timestamp)) = DATE(x.dt)
     GROUP BY x.dt
     ORDER BY x.dt
    

Perché i numeri, non le date?

Semplice:le date possono essere generate in base al numero, come nell'esempio che ho fornito. Significa anche utilizzare una singola tabella, invece di una per tipo di dati.

In precedenza:

  SELECT DATE(FROM_UNIXTIME(v.timestamp)) AS dt,
         COUNT(v.aid)
    FROM VOTES v
   WHERE DATE(FROM_UNIXTIME(v.timestamp)) BETWEEN DATE_SUB(CURRENT_DATE, INTERVAL 7 DAY)
                                              AND CURRENT_DATE
GROUP BY DATE(FROM_UNIXTIME(v.timestamp))