connect by
您可以使用分层查询的语法构建一个包含月份数字的虚拟表,然后左连接到您的数据:
with months as (
select to_char(level, 'FM00') as month
from dual
connect by level <= 12
)
select m.month,
count(mdt.rowid) as counter
from months m
left join mydatatable mdt
on mdt.date_entered >= to_date('01/' || m.month || '/2011', 'DD/MM/YYYY')
and mdt.date_entered <
add_months(to_date('01/' || m.month || '/2011', 'DD/MM/YYYY'), 1)
group by m.month
order by m.month;
使用一些虚构的数据:
create table mydatatable (date_entered date, dummy number);
insert into mydatatable values (date '2011-06-02', 0);
insert into mydatatable values (date '2011-07-01', 0);
insert into mydatatable values (date '2011-10-01', 0);
insert into mydatatable values (date '2011-10-31', 0);
insert into mydatatable values (date '2011-11-01', 0);
...这给出了:
MONTH COUNTER
----- -------
01 0
02 0
03 0
04 0
05 0
06 1
07 1
08 0
09 0
10 2
11 1
12 0
或者SQL Fiddle,因为这似乎是这些天要做的事情......
通常最好避免这样的事情,to_char(date_entered, 'yyyy') = '2011'
因为您将该to_char()
函数应用于表中的每一行,并且如果该列上有索引,则不会使用它。而是尝试转换您的过滤器以匹配列的数据类型,例如date_entered > date '2011-01-01' and date_entered < date '2012-01-01'
. 在这种情况下,无论如何都可以在连接条件中处理它 - 我将每个月转换为 2011 年的日期范围,并且只查找该月份范围内的匹配记录。