MYSQL выбрать количество строк, выпадающих в месяц на каждый месяц года
Со столом:
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 ответ
Решение
MySQL не имеет рекурсивной функциональности, поэтому вам нужно использовать табличный трюк NUMBERS -
Создайте таблицу, которая содержит только увеличивающиеся числа - это легко сделать с помощью 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;
Заполните таблицу, используя:
INSERT INTO NUMBERS (id) VALUES (NULL)
... столько ценностей, сколько вам нужно.
Используйте 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
СЛЕДУЮЩИЙ ПРИСОЕДИНЯЙТЕСЬ к своей таблице данных, основанной на временной части:
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