Oracle 获取当前组和上一个组(分区)平均值的差异
Posted
技术标签:
【中文标题】Oracle 获取当前组和上一个组(分区)平均值的差异【英文标题】:Oracle get difference in Average of Current and Previous group (partition) 【发布时间】:2017-05-30 11:43:52 【问题描述】:我使用的是 Oracle 12.1.0.2.0 我想要当前组(分区)的平均值差异 - 前一组(分区)的平均值 我获取当前组平均值的代码是
with rws as (
select rownum x, mod(rownum, 2) y from dual connect by level <= 10
), avgs as (
select x, y, avg(x) over (partition by y) mean from rws
)
select x, y, mean
from avgs;
现在我想要类似的东西:
X Y MEAN PREV_MEAN MEAN_DIFF 4 0 6 8 0 6 2 0 6 6 0 6 10 0 6 9 1 5 6 -1 7 1 5 3 1 5 1 1 5 5 1 5 2 2 3 5 -3 3 2 3 5 2 3 1 2 3 4 2 3AVG(此分区组)- Avg(前一个分区组) 在这种情况下,我需要 ( 5 - 6 ) 在 GROUP_MEAN_DIFFERENCE 列中进行计算。
另外,我如何才能始终获得第一组的平均差异。 在上面的例子中,我需要 (5 - 6) 和 (3 - 6)
你能帮忙吗?
【问题讨论】:
什么是“前一个分区组”?请提供样本数据和期望的结果。 。 .您的示例数据不使用您的 sn-p 中的列。目前尚不清楚您的代码和数据之间的关系是什么。 【参考方案1】:将函数lag()
与ignore nulls
子句一起使用:
select id, val, av, av - lag(av ignore nulls) over (order by id) diff
from (select id, val,
case when row_number() over (partition by id order by null) = 1
then avg(val) over (partition by id) end av
from t)
order by id
测试:
with t (id, val) as (select 1, 44.520 from dual union all
select 1, 47.760 from dual union all
select 1, 50.107 from dual union all
select 1, 48.353 from dual union all
select 1, 47.640 from dual union all
select 2, 48.353 from dual union all
select 2, 50.447 from dual union all
select 2, 51.967 from dual union all
select 2, 45.800 from dual union all
select 2, 46.913 from dual )
select id, val, av, av - lag(av ignore nulls) over (order by id) diff
from (select id, val,
case when row_number() over (partition by id order by null) = 1
then avg(val) over (partition by id) end av
from t)
order by id
输出:
ID VAL AV DIFF
--- ------- ------- -------
1 44.520 47.676
1 47.760
1 50.107
1 48.353
1 47.640
2 48.353 48.696 1.02
2 50.447
2 51.967
2 45.800
2 46.913
【讨论】:
我们可以在没有内部查询的情况下实现这一点吗? 我怀疑。如果我们尝试在avg()
上使用lag()
,我们会得到ORA-30483: window functions are not allowed here
。您可以将内部查询移至 CTE (with
) 部分。以上是关于Oracle 获取当前组和上一个组(分区)平均值的差异的主要内容,如果未能解决你的问题,请参考以下文章