Potrzebujesz OUTER JOIN
dotrzeć każdego dnia między początkiem a końcem, ponieważ jeśli użyjesz INNER JOIN
ograniczy dane wyjściowe tylko do dat, które są połączone (tj. tylko tych dat w tabeli raportu).
Ponadto, gdy używasz OUTER JOIN
musisz zadbać o to, aby warunki zawarte w where clause
nie powodują implicit inner join
; na przykład ORAZ domain_id =1 jeśli użycie w klauzuli WHERE spowoduje pominięcie każdego wiersza, który nie ma tego warunku, ale gdy zostanie użyty jako warunek złączenia, ograniczy tylko wiersze tabeli raportu.
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;
Zmieniłem również tabelę pochodną all_dates, używając DATE_ADD()
by przesunąć punkt wyjścia w przyszłość i zmniejszyłem jego rozmiar. Obie te opcje są opcjami i można je dostosować według własnego uznania.
aby uzyskać identyfikator domeny dla każdego wiersza (jak pokazano w twoim pytaniu), musisz użyć czegoś takiego; Zauważ, że możesz użyć IFNULL()
który jest specyficzny dla MySQL, ale użyłem COALESCE()
który jest bardziej ogólnym SQL. Jednak użycie @parametru, jak pokazano tutaj, jest i tak specyficzne dla 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;