Anda memerlukan OUTER JOIN
untuk tiba di setiap hari antara awal dan akhir karena jika Anda menggunakan INNER JOIN
itu akan membatasi output hanya pada tanggal yang digabungkan (yaitu hanya tanggal tersebut di tabel laporan).
Selain itu, saat Anda menggunakan OUTER JOIN
Anda harus memperhatikan kondisi di where clause
jangan menyebabkan implicit inner join
; misalnya DAN domain_id =1 jika digunakan dalam klausa where akan menekan baris mana pun yang tidak memenuhi kondisi tersebut, tetapi ketika digunakan sebagai kondisi gabungan, klausa tersebut hanya membatasi baris tabel laporan.
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;
Saya juga telah mengubah tabel turunan all_dates, dengan menggunakan DATE_ADD()
untuk mendorong titik awal ke masa depan, dan saya telah mengurangi ukurannya. Keduanya adalah opsi dan dapat diubah sesuai keinginan Anda.
untuk sampai di domain_id untuk setiap baris (seperti yang ditunjukkan dalam pertanyaan Anda), Anda perlu menggunakan sesuatu seperti berikut; Catatan Anda dapat menggunakan IFNULL()
yang khusus MySQL tetapi saya telah menggunakan COALESCE()
yang merupakan SQL yang lebih umum. Namun penggunaan @parameter seperti yang ditunjukkan di sini adalah khusus 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;