希望获得每个月的记录数。但是,几个月没有记录,因此没有返回行。那个月如何计算0?
select months, count(rowid) as counter from (
select to_char(date_entered, 'MM') as months
from mydatatable
where to_char(date_entered, 'yyyy') = '2011'
)
group by months
order by months
结果:
Month Count
01 32
03 12
04 11
06 10
07 222
08 32
甚至尝试使用subq select 1,2,3,4,5,6,7,8,9,10,11,12 from dual
并且无法使其工作。还没有枢轴功能...;(
答案 0 :(得分:2)
你可能最好在表格中存储01到12,但一般方法是使用左连接:
Select
m.Mo,
Count(t.dateentered)
From (
Select '01' As Mo From Dual Union All
Select '02' From Dual Union All
Select '03' From Dual Union All
Select '04' From Dual Union All
Select '05' From Dual Union All
Select '06' From Dual Union All
Select '07' From Dual Union All
Select '08' From Dual Union All
Select '09' From Dual Union All
Select '10' From Dual Union All
Select '11' From Dual Union All
Select '12' From Dual
) m
Left Outer Join
mydatatable t
On
m.Mo = to_char(t.dateentered, 'MM') And
t.dateentered >= DATE'2011-01-01' And
t.dateentered < DATE'2012-01-01'
Group By
m.Mo
Order By
m.Mo
更新使用了一种更加指数友好的限制年份的方式。
答案 1 :(得分:1)
您需要构建自己的12行月“表”并执行左外连接。从您的问题中获取查询,并使其成为内联视图以提供数据。
SELECT m.month "Month", nvl(md.data, 0) "Count"
FROM
(
select '01' month from dual union all
select '02' month from dual union all
select '03' month from dual union all
select '04' month from dual union all
select '05' month from dual union all
select '06' month from dual union all
select '07' month from dual union all
select '08' month from dual union all
select '09' month from dual union all
select '10' month from dual union all
select '11' month from dual union all
select '12' month from dual
) m LEFT OUTER JOIN (
/* Your Query Here */
) md ON m.month = md.month
ORDER BY m.month;
结果应该是这样的:
Month Count
------ ----------
01 32
02 0
03 12
04 11
05 0
06 10
07 222
08 32
09 0
10 0
11 0
12 0
答案 2 :(得分:0)
您可以使用connect by
syntax of a hierarchical query构建包含月份数字的虚拟表格,然后左键加入您的数据:
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年的日期范围,并且仅查找该月范围内的匹配记录。
答案 3 :(得分:0)
这很奇怪......也许我误解了问题或数据......?在您的问题中添加表格和数据始终是个好主意。您应该获得所有月份的所有数据。我试过这个:
SELECT * FROM stack_test
/
CURR_MONTH VAL
---------------
01 10
02 15
03 20
04
05
正如您所看到的,第4个月和第5个月没有值:
SELECT months, COUNT(rowid) counter
FROM
(
SELECT curr_month months
FROM stack_test
)
GROUP BY months
ORDER BY months
/
MONTHS COUNTER
-------------------
01 1
02 1
03 1
04 1
05 1
另一个例子:第2个月没有任何价值,但我仍然可以理解。也许你需要总结你的价值......:
SELECT mth, SUM(val) total_sum, Count(*) total_cnt
FROM
(
SELECT mth, (CASE WHEN Mth = '01' THEN '10' ELSE '0' END) val
FROM
( -- Annual table - replace 2 with 12 in Add_Months for the whole year --
SELECT Trunc(SYSDATE,'Y')+Level-1 Curr_Year_By_Date
, To_char(Trunc(SYSDATE, 'MM') + Rownum-1, 'MM' ) Mth
FROM dual
CONNECT BY Level <= Add_Months(Trunc(SYSDATE,'Y'),2)-Trunc(SYSDATE,'Y')
)
)
GROUP BY mth
ORDER BY 1
/
MTH TOTAL_SUM TOTAL_CNT
-------------------------------------
01 310 31
02 0 28