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

Agrupación por fecha, fila de retorno incluso si no se encuentran registros

MySQL no tiene funcionalidad recursiva, por lo que te queda usar el truco de la tabla NUMBERS -

  1. Cree una tabla que solo contenga números incrementales, fácil de hacer usando un auto_incremento:

    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. Complete la tabla usando:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...para tantos valores como necesites.

  3. Use DATE_ADD para construir una lista de fechas, aumentando los días según el valor de NUMBERS.id. Reemplace "2010-01-01" y "2010-03-01" con sus respectivas fechas de inicio y finalización (pero use el mismo formato, AAAA-MM-DD) -

    SELECT x.*
      FROM (SELECT DATE_ADD('2010-01-01', INTERVAL n.id - 1 DAY)
              FROM numbers n
             WHERE DATE_ADD('2010-01-01', INTERVAL n.id -1 DAY) <= '2010-03-01' ) x
    
  4. LEFT JOIN en su tabla de datos según la porción de fecha y hora:

       SELECT DATE(x.dt) AS dt,
              COALESCE(SUM(e.value), 0) AS sum_value
         FROM (SELECT DATE_ADD('2010-01-01', INTERVAL n.id - 1 DAY) AS dt
                 FROM numbers n
                WHERE DATE_ADD('2010-01-01', INTERVAL n.id -1 DAY) <= '2010-03-01' ) x
    LEFT JOIN ENTRY e ON DATE(e.datetime) = x.dt
                     AND e.entryid = 85
     GROUP BY DATE(x.dt) 
    

¿Por qué números, no fechas?

Simple:las fechas se pueden generar en función del número, como en el ejemplo que proporcioné. También significa usar una sola tabla, en vez de una por tipo de datos.