我正在尝试返回在特定月份注册的人数,但是也希望在数据库中没有的月份内返回零。
以下查询返回数据库中以月份注册的人数:
select
extract(year from "DATECREATED") as YEAR,
extract(month from "DATECREATED") as mon,
count("USERID") as Total
from
TBLG2O_USEROFO
where
extract(year from "DATECREATED") = '2014'
group by
extract(year from "DATECREATED"),
extract(month from "DATECREATED")
order by
1, 2
答案 0 :(得分:1)
我在mysql上测试了这个,所以你可能需要对oracle进行一些修改。
首先创建一个包含一年中几个月的表格...
create table months(month int);
insert into months values(1);
insert into months values(2);
insert into months values(3);
insert into months values(4);
insert into months values(5);
insert into months values(6);
insert into months values(7);
insert into months values(8);
insert into months values(9);
insert into months values(10);
insert into months values(11);
insert into months values(12);
使用与Month表的右连接来达到预期的效果:
select coalesce(YEAR, 2014) year, m.month, coalesce(Total, 0) as total
from
(select year(DATECREATED) as YEAR, month(c. DATECREATED) month, count("DATECREATED") as Total
from comments c
where year(DATECREATED) ='2014'
group by year, month(c.date_sent)) as c
right join months m
on c.month = m.month
order by year, month
如果您无法添加临时表,可以尝试以下方法:
select coalesce(YEAR, 2014) year, m.month, coalesce(Total, 0) as total
from
(select year(DATECREATED) as YEAR, month(c. DATECREATED) month, count("DATECREATED") as Total
from comments c
where year(DATECREATED) ='2014'
group by year, month(c.date_sent)) as c
right join
(select 1 as month union select 2 as month union select 3 as month
union select 4 as month union select 5 as month union select 6 as month
union select 7 as month union select 8 as month union select 9 as month
union select 10 as month union select 11 as month union select 12 as month) m
on c.month = m.month
order by year, month
答案 1 :(得分:0)
不幸的是,要做到这一点,你需要一个只包含每行月份数的第二个表。
假设您创建了一个名为MONTHS
的表,其中包含一列MONTH_NUMBER
,您可以使用此查询创建您要查找的输出 - 它将计算每行的行数您指定的年份的月份,并且在没有行的任何月份显示零。
请注意,此查询也有一个缺点 - 它只能在一个日历年内工作,因此您无法在多年内(例如,2013年7月 - 2014年6月)将其拆分。
SELECT COALESCE(YEAR, 2014) AS YEAR,
MONTHS.MONTH_NUMBER AS MONTH,
COALESCE(TOTAL, 0) AS "MONTH COUNT"
FROM (SELECT EXTRACT(YEAR FROM DATECREATED) AS YEAR,
EXTRACT(MONTH FROM DATECREATED) AS MONTH,
COUNT(DATECREATED) AS TOTAL
FROM TBLG2O_USEROFO
WHERE EXTRACT(YEAR FROM DATECREATED) = '2014'
GROUP BY EXTRACT(YEAR FROM DATECREATED),
EXTRACT(MONTH FROM DATECREATED)) LFT
RIGHT OUTER JOIN MONTHS
ON MONTH_NUMBER = LFT.MONTH
ORDER BY YEAR, MONTH
See this query in action at SQL Fiddle
基本上,这是@Eran's MySQL answer的Oracle版本。
答案 2 :(得分:0)
在Oracle中,当您需要“合成”不直接存在于数据库中的行时,可以使用建模子句。 model keyword
我使用Jared的SQL Fiddle生成更简单的示例,没有任何第二个表:
select * from
(
select count(1) cnt, trunc(datecreated, 'MONTH') dt
from TBLG2O_USEROFO
group by trunc(datecreated, 'MONTH')
)
model
--partition by (department)
dimension by (dt)
measures (cnt, cast (null as number) tech_cnt)
rules sequential order(
tech_cnt[ for dt from to_date('2013-01-01','RRRR-MM-DD')
to to_date('2014-12-31','RRRR-MM-DD')
increment NUMTOYMINTERVAL(1,'MONTH')]
= nvl(cnt[cv(dt)], 0)
)
order by dt;
想象一下查询的结果是Excel工作表。然后,作业tech_cnt[dt] = nvl(cnt[cv(dt), 0)
是一个“excel宏”。