Vous avez besoin d'un OUTER JOIN
pour arriver à chaque jour entre un début et une fin car si vous utilisez un INNER JOIN
cela limitera la sortie aux seules dates qui sont jointes (c'est-à-dire uniquement les dates dans le tableau du rapport).
De plus, lorsque vous utilisez un OUTER JOIN
vous devez prendre soin que les conditions dans la where clause
ne provoque pas de implicit inner join
; par exemple AND domain_id =1 si l'utilisation dans la clause where supprimerait toute ligne pour laquelle cette condition n'était pas remplie, mais lorsqu'elle est utilisée comme condition de jointure, elle restreint uniquement les lignes de la table de rapport.
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;
J'ai également modifié la table dérivée all_dates, en utilisant DATE_ADD()
pour repousser le point de départ dans le futur, et j'en ai réduit la taille. Ces deux éléments sont des options et peuvent être modifiés comme bon vous semble.
pour arriver à un domain_id pour chaque ligne (comme indiqué dans votre question), vous devez utiliser quelque chose comme ce qui suit ; Notez que vous pouvez utiliser IFNULL()
qui est spécifique à MySQL mais j'ai utilisé COALESCE()
qui est SQL plus générique. Cependant, l'utilisation d'un @paramètre comme indiqué ici est de toute façon spécifique à 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;