Вы также можете достичь желаемого с помощью следующего запроса, который может быть проще для понимания:
SELECT
date_table.date,
IFNULL(SUM(value),0) as sum_val
FROM (
SELECT DATE_ADD('2020-01-01', INTERVAL (@i:=@i+1)-1 DAY) AS `date`
FROM information_schema.columns,(SELECT @i:=0) gen_sub
WHERE DATE_ADD('2020-01-01',INTERVAL @i DAY) BETWEEN '2020-01-01' AND '2020-01-08'
) date_table
LEFT JOIN test ON test.date_value = date_table.date
GROUP BY date;
НАЙТИ ДЕМО ЗДЕСЬ
Вы можете установить некоторую переменную для фиксирования минимальной и максимальной дат:
SET @date_min = '2020-01-01';
SET @date_max = '2020-01-08';
SELECT DATE_ADD(@date_min, INTERVAL (@i:=@i+1)-1 DAY) AS `date`
FROM information_schema.columns, (SELECT @i:=0) gen_sub
WHERE DATE_ADD(@date_min, INTERVAL @i DAY) BETWEEN @date_min AND @date_max
Некоторое объяснение:
На самом деле, ваш вопрос побуждает нас генерировать набор даты, потому что мы ищем «левое соединение» с вашей таблицей с непрерывным набором дат, чтобы сопоставить даты без записей в «вашей таблице».
Это было бы довольно просто в PostgreSQL из-за функции generate_series, но это не так просто в MySQL, поскольку такой полезной функции не существует. Вот почему мы должны быть умными.
Оба решения имеют один и тот же лог c: я имею в виду, что они оба увеличивают значение даты (день в день) для каждой строки, объединенной в другой таблице, назовем ее «исходной таблицей». В ответе выше (не моем) «исходная таблица» состоит из множества объединений и перекрестных объединений (генерирует 100 тыс. Строк), в моем случае здесь «исходная таблица» - это «information_schema.columns», которая уже содержит много строк (1800 +).
В указанном выше случае начальная дата устанавливается на 1970-01-01, а затем она будет увеличивать эту дату в 100 000 раз, чтобы иметь набор из 100 000 дат, начинающихся с 1970-01-01.
В моем случае начальная дата фиксируется на минимальной дате диапазона 2020-01-01, а затем она будет увеличивать эту дату для каждой строки, найденной в information_schema.columns, так что примерно в 1800 раз. Вы закончите с набором из примерно 1800 дат, начиная с 2020-01-01.
Наконец, вы можете присоединиться к своей таблице с этим сгенерированным набором дат (каким бы способом это ни было), чтобы суммировать (значение) для каждого дня в нужном диапазоне.
Надеюсь, что это поможет вам понять логику c, стоящую за обоими запросами;)