Sie benötigen einen OUTER JOIN
um jeden Tag zwischen einem Anfang und einem Ende anzukommen, denn wenn Sie einen INNER JOIN
verwenden Dadurch wird die Ausgabe auf die verknüpften Daten beschränkt (d. h. nur auf die Daten in der Berichtstabelle).
Außerdem, wenn Sie einen OUTER JOIN
verwenden Sie müssen auf Bedingungen in der where clause
achten verursachen keinen implicit inner join
; zum Beispiel UND domain_id =1 if-Verwendung in der where-Klausel würde jede Zeile unterdrücken, die diese Bedingung nicht erfüllt, aber wenn sie als Join-Bedingung verwendet wird, schränkt sie nur die Zeilen der Berichtstabelle ein.
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;
Ich habe auch die abgeleitete Tabelle all_dates geändert, indem ich DATE_ADD()
verwendet habe um den Ausgangspunkt in die Zukunft zu verschieben, und ich habe die Größe reduziert. Beides sind Optionen und können nach Belieben angepasst werden.
um zu einer domain_id für jede Zeile zu gelangen (wie in Ihrer Frage gezeigt), müssten Sie etwas wie das Folgende verwenden; Beachten Sie, dass Sie IFNULL()
verwenden könnten Das ist MySQL-spezifisch, aber ich habe COALESCE()
verwendet das ist allgemeineres SQL. Die Verwendung eines @-Parameters, wie hier gezeigt, ist jedoch ohnehin MySQL-spezifisch.
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;