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

Gruppering efter dato, returner række, selvom der ikke blev fundet nogen poster

MySQL har ikke rekursiv funktionalitet, så du står tilbage med at bruge NUMBERS tabeltricket -

  1. Opret en tabel, der kun indeholder stigende tal - let at lave ved hjælp af et 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. Udfyld tabellen med:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
     

    ...for så mange værdier, som du har brug for.

  3. Brug DATE_ADD for at konstruere en liste over datoer, øge dagene baseret på NUMBERS.id-værdien. Erstat "2010-01-01" og "2010-03-01" med dine respektive start- og slutdatoer (men brug samme format, ÅÅÅÅ-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 på din tabel med data baseret på dato- og tidsdelen:

    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)

Hvorfor tal, ikke datoer?

Simpel - datoer kan genereres baseret på antallet, som i det eksempel, jeg gav. Det betyder også at bruge en enkelt tabel, i modsætning til f.eks. én pr. datatype.




  1. INSERT INTO ... SELECT uden at detaljere alle kolonner

  2. Sådan læser du MySQL binære logfiler (BinLog) med mysqlbinlog

  3. SQL count(*) ydeevne

  4. Skær i MySQL