Potřebujete OUTER JOIN
dostat se na každý den mezi začátkem a koncem, protože pokud použijete INNER JOIN
omezí výstup pouze na data, která jsou spojena (tj. pouze na data v tabulce přehledu).
Navíc, když použijete OUTER JOIN
musíte dbát na splnění podmínek v where clause
nezpůsobují implicit inner join
; například AND domain_id =1 pokud by použití v klauzuli where potlačilo jakýkoli řádek, který tuto podmínku nesplnil, ale při použití jako podmínka spojení omezí pouze řádky tabulky sestavy.
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;
Také jsem změnil odvozenou tabulku all_dates pomocí DATE_ADD()
abych posunul výchozí bod do budoucnosti, a zmenšil jsem jeho velikost. Obě tyto možnosti jsou možnosti a lze je upravit, jak uznáte za vhodné.
k dosažení id_domény pro každý řádek (jak je uvedeno ve vaší otázce) byste museli použít něco jako následující; Všimněte si, že můžete použít IFNULL()
což je specifické pro MySQL, ale použil jsem COALESCE()
což je obecnější SQL. Nicméně použití @parametru, jak je zde uvedeno, je každopádně specifické pro 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;
Podívejte se na to na SQLfiddle