我试图从一组数据中获得12个月的总计,这些数据提供给定月份和年份的分钟数。在许多情况下,我不会有一个月的记录。有没有办法显示丢失的月份,其值为零(0),然后将其翻转或不显示它们,但让查询在12个月范围内确认这一点。以下查询是我试图使用的,但它只是抓住了先前的记录,并没有考虑缺少的月份。下面的查询似乎与某些总数略有不同。非常感谢任何帮助。
Select year
, month
, SUM(NVL(minutes, 0)) OVER (order by year,month rows between 11 preceding and current row) as total_minutes
from
(
Select *
from test_table
Order by year, month
)
Order by year desc , month desc
这是用于创建测试表和数据的sql。
drop table test_table;
create table test_table (
month number(2),
year number(4),
minutes number(4,2)
);
insert into test_table values ( 1, 2012, 3 );
insert into test_table values ( 2, 2012, 3 );
insert into test_table values ( 3, 2012, 3 );
insert into test_table values ( 4, 2012, 4 );
insert into test_table values ( 5, 2012, 5 );
insert into test_table values ( 7, 2012, 5 );
insert into test_table values ( 8, 2012, 5 );
insert into test_table values ( 9, 2012, 5 );
insert into test_table values (10, 2012, 4 );
insert into test_table values (11, 2012, 3 );
insert into test_table values (12, 2012, 3 );
insert into test_table values ( 1, 2011, 3 );
insert into test_table values ( 2, 2011, 3 );
insert into test_table values ( 5, 2011, 5 );
insert into test_table values ( 6, 2011, 5 );
insert into test_table values ( 7, 2011, 5 );
insert into test_table values ( 8, 2011, 5 );
insert into test_table values ( 9, 2011, 5 );
insert into test_table values (10, 2011, 4 );
insert into test_table values (11, 2011, 3 );
insert into test_table values (12, 2011, 3 );
insert into test_table values ( 1, 2010, 3 );
insert into test_table values ( 2, 2010, 3 );
insert into test_table values ( 3, 2010, 3 );
insert into test_table values ( 4, 2010, 4 );
insert into test_table values ( 5, 2010, 4 );
insert into test_table values ( 6, 2010, 5 );
insert into test_table values ( 7, 2010, 5 );
insert into test_table values (10, 2010, 4 );
insert into test_table values (11, 2010, 4 );
insert into test_table values (12, 2010, 3 );
COMMIT;
答案 0 :(得分:0)
要填补几个月的空白,partition outer join
(Oracle 10g广告更高)用于以下查询,如果您确实需要查看这些零,否则您可以保留原始查询重写SUM
功能为SUM(NVL(minutes, 0)) OVER (partition by year order by year,month) as total_minutes
。
SQL> with m_num as(
2 select level as mn
3 from dual
4 connect by level <= 12
5 )
6 select year
7 , mn
8 , minutes
9 , sum(minutes) over(partition by year order by year, mn) rt
10 from ( select tt.Year
11 , mn.mn
12 , nvl(tt.minutes, 0) minutes
13 from test_table tt
14 partition by (tt.year)
15 right outer join m_num mn
16 on (tt.month = mn.mn)
17 )
18 order by year desc, mn desc
19 ;
YEAR1 MN MINUTES RT
----- ---------- ---------- ----------
2012 12 3 43
2012 11 3 40
2012 10 4 37
2012 9 5 33
2012 8 5 28
2012 7 5 23
2012 6 0 18
2012 5 5 18
2012 4 4 13
2012 3 3 9
2012 2 3 6
2012 1 3 3
2011 12 3 41
2011 11 3 38
2011 10 4 35
2011 9 5 31
2011 8 5 26
2011 7 5 21
2011 6 5 16
2011 5 5 11
2011 4 0 6
2011 3 0 6
2011 2 3 6
2011 1 3 3
答案 1 :(得分:0)
我确实使用了外连接,但这并没有给我提供我所需要的12个月滚动范围。我不得不使用Windowing Clause来获得正确的范围和数字。
with m_num as(
select level as mn
from dual
connect by level <= 12
)
select year
, mn
, minutes
, sum(minutes) over(order by year,mn rows between 11 preceding and current row) rt
from ( select tt.Year
, mn.mn
, nvl(tt.minutes, 0) minutes
from test_table tt
partition by (tt.year)
right outer join m_num mn
on (tt.month = mn.mn)
)
order by year desc, mn desc;