动态运行总计

时间:2013-06-01 03:02:50

标签: sql oracle

我想创建一个返回几个月雨总数的视图。视图返回的每一行代表给定年份的一个月。

在视图中,我想要包含一年中累积降雨量的列,以便1月份的行将具有该年1月份的总降雨量。 2月的行将为{y 1}的Jan+Feb的总雨量,3月的行将为Jan+Feb+Mar的总雨量...等等到12月12月将有总雨量这一年。

困难的部分是我希望能够查询特定日期的视图 恩。 “select * from vw_rain_stats where rain_date >= to_date('2010-MAR-01')”和累计总和列应从where子句(March)中指定的月开始累计,而不是1月。

我不希望2010年-MAR-01之前的每月雨量都包含在视图返回的数据中。

我可以开发一个整体累积amts的视图,但我无法弄清楚如何开发视图,以便它可以开始累积一个月以外的月份。

鉴于2012年1月至2013年2月期间基础表中的数据以及该时段的每个月都有一些降雨(没有零下雨)。

create table rain_stats (rain_date date, amt number);

insert into rain_stats values ('2012-JAN-01', 50);
insert into rain_stats values ('2012-FEB-01', 10);
insert into rain_stats values ('2012-MAR-01', 20);
insert into rain_stats values ('2012-APR-01', 40);
insert into rain_stats values ('2012-MAY-01', 30);
insert into rain_stats values ('2012-JUN-01', 10);
insert into rain_stats values ('2012-JUL-01', 4);
insert into rain_stats values ('2012-AUG-01', 100);
insert into rain_stats values ('2012-SEP-01', 5);
insert into rain_stats values ('2012-OCT-01', 100);
insert into rain_stats values ('2012-NOV-01', 90);
insert into rain_stats values ('2012-DEC-01', 80);
insert into rain_stats values ('2013-JAN-01', 30);
insert into rain_stats values ('2013-FEB-01', 7);

用户执行此查询

select * from vw_rain_stats where rain_date >= '2012-MAY-01'

这是返回的结果;

|          RAIN_DATE | AMT | RUNNING_AMT |
------------------------------------------
|      May, 01 2012  |  30 |          30 |
|      Jun, 01 2012  |  10 |          40 |
|      Jul, 01 2012  |   4 |          44 |
|      Aug, 01 2012  | 100 |         144 |
|      Sep, 01 2012  |   5 |         149 |
|      Oct, 01 2012  | 100 |         249 | 
|      Nov, 01 2012  |  90 |         339 |
|      Dec, 01 2011  |  80 |         419 |
|      Jan, 01 2013  |  30 |          30 |
|      Feb, 01 2013  |  70 |         100 |
| .................. | ... | ........... |

请注意,2012年1月至4月的降雨量不包含在结果集或running_amt累积值中。这就是我想要发生的事情。

3 个答案:

答案 0 :(得分:3)

更新你在找这个吗?

CREATE VIEW vw_rain_stats
AS
  SELECT TRUNC(rain_date, 'MM') rain_date,
         SUM(amt) amt
    FROM rain_stats
   GROUP BY TRUNC(rain_date, 'MM')
;

获取2012年的月度金额

SELECT rain_date,
       amt,
       SUM(amt) OVER (ORDER BY rain_date) running_amt
  FROM vw_rain_stats
 WHERE rain_date BETWEEN '01-JAN-12' AND '01-DEC-12';

从2011年12月开始每月获取金额

SELECT rain_date,
       amt,
       SUM(amt) OVER (ORDER BY rain_date) running_amt
  FROM vw_rain_stats
 WHERE rain_date >= '01-DEC-11';

示例输出:

|          RAIN_DATE | AMT | RUNNING_AMT |
------------------------------------------
| December, 01 2011  |  80 |          80 |
|  January, 01 2012  |  30 |         110 |
| February, 01 2012  |  70 |         180 |
|    March, 01 2012  | 110 |         290 |
| .................. | ... | ........... |

这是 SQLFiddle 演示

答案 1 :(得分:0)

我不确定我是否完全遵循你所追求的内容,但这听起来像是你想要一个Window功能的情况。如果您将其添加到视图中:

SUM(Rain_Amt) OVER (ORDER BY rain_date) AS cum_Rain

您可以从任何日期开始累积降雨量,从每个后续日期减去开始日期的累积降雨量,例如:

SELECT *, cum_Rain - (SELECT cum_Rain FROM vw_rain_stats WHERE rain_date = '20070405')
FROM vw_rain_stats
WHERE rain_date >= '20070405'

答案 2 :(得分:0)

我假设您有一个基础表RainDays,这是每日降雨量。

你会认为你想要的是以下观点:

create view vw_RainMonths as
    select yyyymm, RainMonth,
            sum(RainMonth) over (order by yyyymm) as cum
    from (select to_char(RainDate as 'YYYY-MM') as yyyymm, sum(Rain) as RainMonth
          from RainDays
          group by to_char(RainDate as 'YYYY-MM')
         ) t

但是,这不起作用,因为(正如您所怀疑的)它会从一开始就累积值。 where子句适用于此数据。

Oracle确实支持表值函数,参数化视图和流水线表函数 - 所有这些函数都可以充当视图并在参数中应用值。不幸的是,这些都不像单一视图一样干净。它们需要为返回值创建新的数据类型。