Du skal bruge en OUTER JOIN
at ankomme hver dag mellem start og slut, fordi hvis du bruger en INNER JOIN
det vil begrænse output til kun de datoer, der er sammenføjet (dvs. kun disse datoer i rapporttabellen).
Derudover, når du bruger en OUTER JOIN
du skal passe på, at betingelserne i where clause
forårsager ikke en implicit inner join
; for eksempel AND domain_id =1 hvis brug i where-sætningen ville undertrykke enhver række, der ikke havde denne betingelse opfyldt, men når den bruges som en join-betingelse, begrænser den kun rækkerne 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;
Jeg har også ændret tabellen med alle_datoer ved at bruge DATE_ADD()
at skubbe udgangspunktet ind i fremtiden, og jeg har reduceret dens størrelse. Begge disse er muligheder og kan justeres, som du finder passende.
for at nå frem til et domæne_id for hver række (som vist i dit spørgsmål) skal du bruge noget som det følgende; Bemærk, at du kan bruge IFNULL()
som er MySQL-specifik, men jeg har brugt COALESCE()
som er mere generisk SQL. Men brugen af en @parameter som vist her er MySQL-specifik alligevel.
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;