2

我想创建一个视图来返回几个月的降雨量。视图返回的每一行将代表给定年份的一个月。

在视图中,我想包含一列是一年中的累积降雨量,这样一月的一行将包含当年一月的总降雨量。2 月的行将具有当年的总降雨量Jan+Feb,3 月的行将具有Jan+Feb+Mar...的总降雨量,依此类推,直到 12 月。12 月将具有当年的总降雨量。

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

我不希望 2010 年 3 月 1 日之前的任何月降雨量包含在视图返回的数据中。

我可以开发一个累积全年 amts 的视图,但我不知道如何开发该视图以便它可以开始累积除 1 月以外的一个月的 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'

这是返回的结果;

| 雨日期 | AMT | 运行_AMT |
------------------------------------------
| 2012 年 5 月 1 日 | 30 | 30 |
| 2012 年 6 月 1 日 | 10 | 40 |
| 2012 年 7 月 1 日 | 4 | 44 |
| 2012 年 8 月 1 日 | 100 | 144 |
| 2012 年 9 月 1 日 | 5 | 149 |
| 2012 年 10 月 1 日 | 100 | 249 |
| 2012 年 11 月 1 日 | 90 | 339 |
| 2011 年 12 月 1 日 | 80 | 419 |
| 2013 年 1 月 1 日 | 30 | 30 |
| 2013 年 2 月 1 日 | 70 | 100 |
| ..... | ... | ...... |

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

4

3 回答 3

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演示

于 2013-06-01T03:44:05.763 回答
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 确实支持表值函数、参数化视图和流水线表函数——所有这些都可以作为获取视图并在参数中应用值。不幸的是,这些都不像单一视图那样干净。他们需要为返回值创建一个新的数据类型。

于 2013-06-01T05:25:32.273 回答
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'
于 2013-06-01T03:52:55.300 回答