Je hebt een OUTER JOIN
nodig om elke dag tussen een begin en een einde aan te komen, want als je een INNER JOIN
. gebruikt het zal de uitvoer beperken tot alleen de datums die zijn samengevoegd (d.w.z. alleen die datums in de rapporttabel).
Bovendien, wanneer u een OUTER JOIN
. gebruikt u moet ervoor zorgen dat de voorwaarden in de where clause
veroorzaak geen implicit inner join
; bijvoorbeeld AND domain_id =1 als het gebruik in de where-clausule elke rij zou onderdrukken waaraan niet aan die voorwaarde werd voldaan, maar wanneer gebruikt als een join-voorwaarde, beperkt het alleen de rijen van de rapporttabel.
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;
Ik heb ook de afgeleide tabel all_dates gewijzigd met behulp van DATE_ADD()
om het startpunt naar de toekomst te duwen, en ik heb de omvang ervan verkleind. Beide zijn opties en kunnen naar eigen inzicht worden aangepast.
om voor elke rij tot een domain_id te komen (zoals weergegeven in uw vraag), zou u iets als het volgende moeten gebruiken; Merk op dat u IFNULL()
. kunt gebruiken wat MySQL-specifiek is, maar ik heb COALESCE()
. gebruikt wat meer generieke SQL is. Het gebruik van een @parameter zoals hier getoond is hoe dan ook MySQL-specifiek.
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;