Конечно, осталось присоединить его к коллекции всех 12 месяцев. Это MySQL (потому что вы использовали псевдоним GROUP BY, который, я думаю, только MySQL, может быть, Postgres тоже):
WITH months as (
SELECT 1 as m
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
UNION ALL SELECT 9
UNION ALL SELECT 10
UNION ALL SELECT 11
UNION ALL SELECT 12
)
SELECT
m.m,
sum (p.price) as s
FROM
months m
LEFT JOIN product p
ON
m.m = MONTH(p.created) AND
p.created > '2020-01-01' and p.Created < '2021-01-01'
GROUP BY
m.m
Месяцы, которые не совпадают, будут иметь значение NULL, что будет суммироваться как 0
. Вы должны попытаться не использовать такие функции, как YEAR () в предложении WHERE, поскольку они означают, что индексы использовать нельзя; вместо этого оставьте данные таблицы в покое и вместо них поместите поиск по дальности
Если ваш MySQL старый и не поддерживает CTE, сделайте это подзапросом. Если ваша база данных не MySQL / Pg или вам нужно что-то выбрать, вы можете выбрать ее из таблицы, в которой есть только одна строка
Альтернативный трюк, который не использует объединение, будет объединять нагрузку ноль месяцев; они не будут вносить вклад в суммы, но обеспечат месяц 0:
SELECT
m,
sum (price) as s
FROM
(
SELECT MONTH(created) as m, price FROM product WHERE created >= '2020-01-01' and created < '2021-01-01'
UNION ALL SELECT 1, 0 UNION ALL SELECT 2, 0 UNION ALL SELECT 3, 0
UNION ALL SELECT 4, 0 UNION ALL SELECT 5, 0 UNION ALL SELECT 6, 0
UNION ALL SELECT 7, 0 UNION ALL SELECT 8, 0 UNION ALL SELECT 9, 0
UNION ALL SELECT 10, 0 UNION ALL SELECT 11, 0 UNION ALL SELECT 12, 0
) x
GROUP BY
m
Если у вас есть таблица, посвященная числам и датам, блок union all может быть заменен вызовом к нему. Если вы используете Postgres, у него есть последовательный генератор, который может делать крутые вещи