select weekValue, yearValue, coalesce(mycount,0)
from
( SELECT distinct week(@startDate := @startDate + Interval 1 day) as weekValue,
year(@startDate := @startDate + Interval 1 day) as yearValue
FROM
(select 0 union all select 1 union all select 3 union all select 4
union all select 5 union all select 6 union all select 6 union all select 7
union all select 8 union all select 9) t,
(select 0 union all select 1 union all select 3
union all select 4 union all select 5 union all select 6
union all select 6 union all select 7 union all select 8 union all select 9) t2,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3,
(select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4,
(SELECT @startDate := '2017-03-31 00:00:00' ) as g
where
@startDate < '2017-06-01 00:00:00' ) as generateWeekYear left join
(SELECT week(stamp) as theweek, count(*) AS mycount, YEAR(stamp) as theyear
FROM merges
WHERE completed = 1
AND stamp BETWEEN '2017/4/1 00:00:00' AND '2017/6/1 00:00:00' GROUP BY week(stamp) ) as actualQuery
on generateWeekYear.weekValue = actualQuery.theweek
and generateWeekYear.yearValue = actualQuery.theyear
Let me explain the above query,
Sub Query generateWeekYear = This is used to genearate distinct week and year based on two inputs
lets say startDate and endDate. startDate should be 1 day less to actual startDate. Because if you do not
subtract 1 day then there might chance to loose one week.
Now you have all week and year which needs to be displayed.
Now you are thinking generateWeekYear is going to be more time to execute but this is not case. You can
check this generate an integer sequence in MySQL.
After that you simply join your table with above table and you can get your required result.