Necesitas una OUTER JOIN
para llegar a todos los días entre un inicio y un final porque si usa un INNER JOIN
restringirá la salida a solo las fechas que se unen (es decir, solo esas fechas en la tabla del informe).
Además, cuando usa un OUTER JOIN
debe tener cuidado de que las condiciones en la cláusula where clause
no provoque una implicit inner join
; por ejemplo Y ID_dominio =1 si el uso en la cláusula where suprimiría cualquier fila que no cumpliera con esa condición, pero cuando se usa como una condición de combinación, solo restringe las filas de la tabla de informes.
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;
También he cambiado la tabla derivada all_dates, usando DATE_ADD()
para empujar el punto de partida hacia el futuro, y he reducido su tamaño. Ambas son opciones y se pueden ajustar como mejor le parezca.
para llegar a un domain_id para cada fila (como se muestra en su pregunta), necesitaría usar algo como lo siguiente; Tenga en cuenta que podría usar IFNULL()
que es específico de MySQL pero he usado COALESCE()
que es un SQL más genérico. Sin embargo, el uso de un @parámetro como se muestra aquí es específico de MySQL de todos modos.
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;