Как добавить в результат MySQL даты, по которым нет записей в базе данных? - PullRequest
0 голосов
/ 29 марта 2012

Рассмотрим следующую таблицу «сообщений»:

_date        message
-------------------------
2012-02-22   hello
2012-02-22   another msg!
2012-03-05   foobar
2012-03-22   testing
2012-03-22   goodbye
2012-03-22   test test

Я хочу посчитать количество сообщений в день, но также хочу включить все дни, в которые нет сообщений. Скажем, я хочу посчитать все сообщения между 2012-02-01 и 2012-03-29, тогда результат запроса должен быть:

_date        messsages
----------------------
2012-02-01   0
2012-02-02   0
...
2012-02-22   2
2012-02-23   0
...
2012-03-01   0
2012-03-02   0
2012-03-03   0
2012-03-04   0
2012-03-05   1
...
2012-03-22   3
...
2012-03-29   0

Возможно ли это в MySQL?

Ответы [ 4 ]

2 голосов
/ 29 марта 2012

Что-то вроде этого должно сделать это -

SELECT date_range.`date`, COUNT(messages._date)
FROM (
    SELECT '2012-02-01' + INTERVAL (id - 1) DAY AS `date`
    FROM dummy
    WHERE id BETWEEN 1 AND 58
    ORDER BY id ASC
) AS date_range
LEFT JOIN messages
    ON date_range.`date` = messages._date
GROUP BY date_range.`date` ASC

В этом примере фиктивная таблица - это любая таблица с целочисленным полем идентификатора с непрерывным набором, охватывающим требуемый диапазон дат. В этом случае вам понадобятся идентификаторы от 1 до 58.

0 голосов
/ 29 марта 2012

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

0 голосов
/ 29 марта 2012

Я нашел похожее решение, используя ключевое слово МЕЖДУ другим ответом здесь. Я раньше не использовал BETWEEN в SQL, но это выглядит многообещающе. Я не уверен, будет ли он считать 0 для дней, которых нет в таблице, но это может помочь вам начать хотя бы.

Они также упоминают о более уродливом методе использования вспомогательной таблицы против JOIN; это определенно даст вам 0 очков, но, на мой взгляд, будет немного грязно. Если вы решите пойти по этому пути, я бы предложил попробовать временную таблицу, возможно, используя CREATE TEMPORARY TABLE.

https://stackoverflow.com/a/895185/1301139

0 голосов
/ 29 марта 2012

Как указано здесь , вам нужно будет использовать хранимую процедуру, которая создаст временную таблицу со всеми датами в диапазоне и присоединит к ней таблицу сообщений. Вы не можете вернуть записи из таблицы, в которой их нет.

...