MYSQL выбрать количество строк, выпадающих в месяц на каждый месяц года - PullRequest
1 голос
/ 02 августа 2010

со столом:

id   date_from    date_to
---------------------------
1    2010-01-01   2010-03-01
2    2010-02-07   2010-05-01
3    2010-07-05   2010-07-10

Я пытаюсь вернуть результат с одной строкой для каждого месяца года, который позволяет мне узнать, сколько строк было активным за этот период.

Так что для вышесказанного я бы хотел получить результат

2010-01-01 1
2010-02-01 2
2010-03-01 2
2010-04-01 1
2010-05-01 1
2010-06-01 0
2010-07-01 1
2010-08-01 0
2010-09-01 0
etc...

Я пытался сгруппировать свой МЕСЯЦ (date_from), но это не возвращает строки без результатов

1 Ответ

2 голосов
/ 02 августа 2010

MySQL не имеет рекурсивной функциональности, поэтому вам остается использовать табличный трюк NUMBERS -

  1. Создать таблицу, содержащую только увеличивающиеся числа - это легко сделать с помощью 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. Заполните таблицу, используя:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ... столько раз, сколько вам нужно.

  3. Используйте DATE_ADD , чтобы составить список раз, увеличив месяцы, основываясь на значении NUMBERS.id:

    SELECT x.*
      FROM (SELECT DATE_FORMAT(DATE_ADD('2010-01-01', INTERVAL n.id - 1 MONTH), '%Y-%m-%d') 
              FROM numbers n) x
    
  4. СЛЕВАЯ ПРИСОЕДИНЯЙТЕСЬ к своей таблицеданные основаны на временной части:

       SELECT x.ts AS timestamp,
              SUM(CASE WHEN x.ts BETWEEN y.date_from AND y.date_to THEN 1 ELSE 0 END) AS cnt
         FROM (SELECT DATE_FORMAT(DATE_ADD('2010-01-01', INTERVAL n.id - 1 MONTH), '%Y-%m-%d') AS ts
                 FROM numbers n) x
    LEFT JOIN TABLE y ON x.ts BETWEEN y.date_from AND y.date_to
     GROUP BY x.ts
    
...