You could also achieve what you want with the following query which may be easier to understand :
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;
FIND A DEMO HERE
You could set some variable to fix min and max dates :
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
Some explanation :
In fact, your question encourage us to generate a set of dates because we are looking to 'left join' 'your table' with a continuous set of date in order to match dates with no records in 'your table'.
This would be pretty easy in PostgreSQL because of generate_series function but this is not that easy in MySQL as such a useful function doesn't exist. That's why we need to be smart.
Both solutions here have the same logic behind it : I mean they are both incrementing a date value (day per day) for each row joined in another table, let's call it 'source table'. In the answer above (not mine), 'source table' is made with many unions and cross joins (it generates 100k rows), in my case here 'source table' is 'information_schema.columns' which already contains lots of rows (1800+).
In above case, initial date is fixed to 1970-01-01 and then it will increment this date 100 000 times in order to have a set of 100 000 dates beginning with 1970-01-01.
In my case, initial date is fixed to your min range date, 2020-01-01, and then it will increment this date for each row found in information_schema.columns, so around 1800 times. You will end with a set of around 1800 dates beginning with 2020-01-01.
Finally, you can left join your table with this generated set of dates (whatever the way to do it) in order to sum(value) for each day in your desired range.
Hope that would help you understand the logic behind both queries ;)