我已经在甲骨文中看到了许多滚动平均值的例子,但是做了我想要的事情 .
这是我的原始数据
DATE SCORE AREA
----------------------------
01-JUL-14 60 A
01-AUG-14 45 A
01-SEP-14 45 A
02-SEP-14 50 A
01-OCT-14 30 A
02-OCT-14 45 A
03-OCT-14 50 A
01-JUL-14 60 B
01-AUG-14 45 B
01-SEP-14 45 B
02-SEP-14 50 B
01-OCT-14 30 B
02-OCT-14 45 B
03-OCT-14 50 B
这是我的滚动平均值的理想结果
MMYY AVG AREA
-------------------------
JUL-14 60 A
AUG-14 52.5 A
SEP-14 50 A
OCT-14 44 A
JUL-14 60 B
AUG-14 52.5 B
SEP-14 50 B
OCT-14 44 B
我需要它的工作方式是,对于每个MMYY,我需要回顾3个月,然后AVG得分 . 所以,例如,
对于OCT的A区,在距离10月的最后3个月中,有6项研究,(45 45 50 30 45 50)/ 6 = 44.1
通常我会像这样编写查询
SELECT
AREA,
TO_CHAR(T.DT,'MMYY') MMYY,
ROUND(AVG(SCORE)
OVER (PARTITION BY AREA ORDER BY TO_CHAR(T.DT,'MMYY') ROWS BETWEEN 2 PRECEDING AND CURRENT ROW),1)
AS AVG
FROM T
这将查看过去3个月内的最后3个回合
3 回答
一种方法是将聚合函数与分析函数混合使用 . 平均值的关键思想是避免使用
avg()
而是使用sum()
除以count(*)
.请注意
order by
子句 . 如果您的数据跨越多年,则使用MMYY格式会产生问题 . 最好使用YYYY-MM等格式数月,因为字母顺序与自然顺序相同 .从下次开始,我希望您提供
create
和insert
语句,这样我们就不必花时间准备test case
.而且,为什么
YY
格式?你没见过Y2K
的错误吗?请使用YYYY
格式 .您也可以指定范围,而不仅仅是行 .
由于
CURRENT ROW
是默认值,因此ORDER BY DT RANGE INTERVAL '3' MONTH PRECEDING
也可以正常工作 . 也许你必须做一些微调,我没有测试关于每月28/29/30/31天问题的行为 .有关详细信息,请查看Oracle Windowing Clause .