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 3

    AVG(此分区组)- 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 获取当前组和上一个组(分区)平均值的差异的主要内容,如果未能解决你的问题,请参考以下文章

LINQ 查询多个组和最新记录的计数 - Oracle DB

没索引oracle无唯一索引交换分区会丢失数据?

SQL SERVER删除文件组和文件

在oracle sql中比较当前行和上一行

oracle在线添加日志组和日志组成员

SQL 表分区