MySQL how to fill missing dates in range?

前端 未结 5 608
离开以前
离开以前 2020-11-21 06:47

I have a table with 2 columns, date and score. It has at most 30 entries, for each of the last 30 days one.

date      score
-----------------
1.8.2010  19
2         


        
5条回答
  •  忘了有多久
    2020-11-21 07:27

    MySQL doesn't have recursive functionality, so you're left with using the NUMBERS table trick -

    1. Create a table that only holds incrementing numbers - easy to do using an 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. Populate the table using:

      INSERT INTO `example`.`numbers`
        ( `id` )
      VALUES
        ( NULL )
      

      ...for as many values as you need.

    3. Use DATE_ADD to construct a list of dates, increasing the days based on the NUMBERS.id value. Replace "2010-06-06" and "2010-06-14" with your respective start and end dates (but use the same format, YYYY-MM-DD) -

      SELECT `x`.*
        FROM (SELECT DATE_ADD('2010-06-06', INTERVAL `n`.`id` - 1 DAY)
                FROM `numbers` `n`
               WHERE DATE_ADD('2010-06-06', INTERVAL `n`.`id` -1 DAY) <= '2010-06-14' ) x
      
    4. LEFT JOIN onto your table of data based on the time portion:

         SELECT `x`.`ts` AS `timestamp`,
                COALESCE(`y`.`score`, 0) AS `cnt`
           FROM (SELECT DATE_FORMAT(DATE_ADD('2010-06-06', INTERVAL `n`.`id` - 1 DAY), '%m/%d/%Y') AS `ts`
                   FROM `numbers` `n`
                  WHERE DATE_ADD('2010-06-06', INTERVAL `n`.`id` - 1 DAY) <= '2010-06-14') x
      LEFT JOIN TABLE `y` ON STR_TO_DATE(`y`.`date`, '%d.%m.%Y') = `x`.`ts`
      

    If you want to maintain the date format, use the DATE_FORMAT function:

    DATE_FORMAT(`x`.`ts`, '%d.%m.%Y') AS `timestamp`
    

提交回复
热议问题