If you really don't want a table.
On Oracle you could do something like:
select D.D, count(T.CompareDate)
from (select to_date('2009-07-01', 'YYYY-MM-DD') + LEVEL - 1 as D
from dual
connect by LEVEL <= 30) D
left outer join T ON T.CompareDate = D.D
group by D.D
Where the date inside to_date is the starting date, and you test against level for the number of days you want in your results.
On SQL Server 2005/2008:
; with X1 (X) as
(select 1 union all select 1)
, X2 (X) as
(select 1 from X1 a cross join X1 b)
, X4 (X) as
(select 1 from X2 a cross join X2 b)
, X8 (X) as
(select 1 from X4 a cross join X4 b)
, X16 (X) as
(select 1 from X8 a cross join X8 b)
, NUM (N) as
(select row_number() over (order by X) from X16)
, D (D) as
(select dateadd(day, N-1, '20090701')
from NUM
where NUM.N <= 30)
select D.D, count(T.CompareDate)
from D
left outer join T on T.CompareDate = D.D
group by D.D
The with clause is to build the Dates. The date specified in the dateadd
is starting date, and number of days is tested at NUM.N <=30
. You could also test against end date where dateadd(day, N-1, StartDate) <= EndDate
I would recommend encapsulating the with clause to create the ranges as an inline table valued function.
The number generation is based on code I've seen from Itzik Ben-gan. Each X gives you number of rows equal to power of 2 of the X number (X1 = 2 rows and X8 = 256 rows.) If you need more that 65,536, you will need to add more cross joins. If you never need more than 256, then you can elimanate X16.
Also, if you have a table of numbers lying around, you can use that and date arithemetic to generate the dates you need on the fly.