Нуждаете се от OUTER JOIN
за да стигнете до всеки ден между началото и края, защото ако използвате INNER JOIN
той ще ограничи изхода само до датите, които са обединени (т.е. само тези дати в таблицата на отчета).
Освен това, когато използвате OUTER JOIN
трябва да се погрижите за условията в where clause
не предизвикват implicit inner join
; например И domain_id =1 ако използването в клаузата where би потиснало всеки ред, който не е отговарял на това условие, но когато се използва като условие за присъединяване, ограничава само редовете на таблицата на отчета.
SELECT
COUNT(r.domain_id)
, all_dates.Date AS the_date
, domain_id
FROM (
SELECT DATE_ADD(curdate(), INTERVAL 2 MONTH) - INTERVAL (a.a + (10 * b.a) ) DAY as Date
FROM (select 0 as a union all select 1 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) as a
CROSS JOIN (select 0 as a union all select 1 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) as b
) all_dates
LEFT OUTER JOIN reports r
ON all_dates.Date = r.tracked_on
AND domain_id = 1
WHERE all_dates.Date BETWEEN '2014-09-01' AND '2014-09-30'
GROUP BY
the_date
ORDER BY
the_date ASC;
Също така промених таблицата, извлечена от all_dates, като използвах DATE_ADD()
за да избутам отправната точка в бъдещето и намалих нейния размер. И двете са опции и могат да бъдат коригирани, както сметнете за добре.
за да стигнете до domain_id за всеки ред (както е показано във вашия въпрос), ще трябва да използвате нещо като следното; Имайте предвид, че можете да използвате IFNULL()
което е специфично за MySQL, но съм използвал COALESCE()
който е по-общ SQL. Въпреки това използването на @параметър, както е показано тук, така или иначе е специфично за MySQL.
SET @domain := 1;
SELECT
COUNT(r.domain_id)
, all_dates.Date AS the_date
, coalesce(domain_id,@domain) AS domain_id
FROM (
SELECT DATE_ADD(curdate(), INTERVAL 2 month) - INTERVAL (a.a + (10 * b.a) ) DAY as Date
FROM (select 0 as a union all select 1 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) as a
CROSS JOIN (select 0 as a union all select 1 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) as b
) all_dates
LEFT JOIN reports r
ON all_dates.Date = r.tracked_on
AND domain_id = @domain
WHERE all_dates.Date BETWEEN '2014-09-01' AND '2014-09-30'
GROUP BY
the_date
ORDER BY
the_date ASC;