Du behöver en OUTER JOIN
att komma fram till varje dag mellan start och slut eftersom om du använder en INNER JOIN
det kommer att begränsa utdata till bara de datum som är sammanfogade (dvs. bara dessa datum i rapporttabellen).
Dessutom, när du använder en OUTER JOIN
du måste se till att villkoren i where clause
orsaka inte en implicit inner join
; till exempel AND domain_id =1 om användning i where-satsen skulle undertrycka alla rader som inte hade det villkoret uppfyllt, men när det används som ett joinvillkor begränsar det bara raderna i rapporttabellen.
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;
Jag har också ändrat den härledda tabellen för alla_datum genom att använda DATE_ADD()
för att driva utgångspunkten in i framtiden, och jag har minskat dess storlek. Båda dessa är alternativ och kan justeras som du vill.
för att komma fram till ett domän-id för varje rad (som visas i din fråga) måste du använda något i stil med följande; Observera att du kan använda IFNULL()
som är MySQL-specifik men jag har använt COALESCE()
vilket är mer generisk SQL. Men användningen av en @parameter som visas här är MySQL-specifik ändå.
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;