Skip to Main Content
  • Questions
  • How to get Difference between AVG of two groups with windowing function(current group Avg - Previous group Avg)

Breadcrumb

Question and Answer

Chris Saxon

Thanks for the question, Rohini.

Asked: May 30, 2017 - 10:59 am UTC

Last updated: May 30, 2017 - 4:40 pm UTC

Version: Oracle 12.1.0.2.0

Viewed 1000+ times

You Asked

Hello Tom,

I am using following code to get average of group data partition by group id. I am getting correct values for current group with following code.

I am using Oracle 12.1.0.2.0
I want difference in average of current group(partition) - average of previous group(partition)
My code to get current group Average is

    select
      case
        when LAG(CTGE."GROUP_ID", 1, -1) OVER (ORDER BY CTGE.ORDER_INDEX ASC) != CTGE."GROUP_ID" then
          AVG(BI_COMET_ASSAY_REPORT.ANALYSE_PARAMETER_PER_ANIMAL(CSMA.ASSAY_ID, CSMAN.ANIMAL_ID, BI_COMET_ASSAY_REPORT.GET_TISSUE_BY_INDEX(CSMA.ASSAY_ID, 1), 'TAIL_INTENSITY', 'AVG','AVG')) over (PARTITION BY CTGE."GROUP_ID" ORDER BY CTGE.ORDER_INDEX ASC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
      end as GROUP_MEAN,
      case
        when LAG(CTGE."GROUP_ID", 1, -1) OVER (ORDER BY CTGE.ORDER_INDEX ASC) != CTGE."GROUP_ID" then
          AVG(BI_COMET_ASSAY_REPORT.ANALYSE_PARAMETER_PER_ANIMAL(CSMA.ASSAY_ID, CSMAN.ANIMAL_ID, BI_COMET_ASSAY_REPORT.GET_TISSUE_BY_INDEX(CSMA.ASSAY_ID, 1), 'TAIL_INTENSITY', 'AVG','AVG')) over (PARTITION BY CTGE."GROUP_ID" ORDER BY CTGE.ORDER_INDEX ASC RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
      end as GROUP_MEAN_DIFFERENCE
    from
      CSM_ASSAYS CSMA,
      CSM_ANIMALS CSMAN,
      CSM_TREATMENT_GROUPS CTG,
      CSM_TREATMENT_GROUPS_EXPTS CTGE
    where 
      CSMA.ASSAY_ID = 1 and 
      CSMAN."GROUP_ID" = CTG."GROUP_ID" and
      CTG."GROUP_ID" = CTGE."GROUP_ID" and
      CTGE.EXPERIMENT_ID = CSMA.EXPT_ID and
      CSMAN.IS_MALE = 1 and
      CSMAN.IS_INVALID = 0 and
      BI_COMET_ASSAY_REPORT.GET_TISSUE_BY_INDEX(CSMA.ASSAY_ID, 1) is not null
    order by
      CTGE.ORDER_INDEX ASC,
      TO_NUMBER(CSMAN.ANIMAL_CODE) ASC;


Now I want something like :

    Mean         | Group Mean        | Group Mean Difference
    
    44.520       |  47.676           |       -   
    47.760       |                   |
    50.107       |                   |
    48.353       |                   |
    47.640       |                   |
    ----------------------------------------------------
    48.353       |     48.696        | 1.02
    50.447       |                   |
    51.967       |                   |
    45.800       |                   |
    46.913       |                   |

AVG( this partitioned group) - Avg( previous partition group)
In this case I need ( 48.696 - 47.676 ) to compute in GROUP_MEAN_DIFFERENCE column.

Can you please assist?



How can I achieve this?

and Chris said...

To get the difference between the means while still viewing all the rows, you can:

1: Get the avg within the group with avg(...) over (partition by ...)
2: Use last_value to find the avg from the previous group.

Lag doesn't work at step 2 because it operates on rows. You don't know how many there are in each group. With last_value you can use the windowing clause:

range between unbounded preceding and 1 preceding


If you order by your grouping column, this will search all the rows up to the value of the current group - 1. Put it all together and you get:

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, 
         last_value(mean) over (
           order by y range between unbounded preceding and 1 preceding
         ) prev_mean,
         mean - last_value(mean) over (
           order by y range between unbounded preceding and 1 preceding
         ) mean_diff
  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     6          -1         
3   1  5     6          -1         
1   1  5     6          -1         
5   1  5     6          -1

Rating

  (1 rating)

Is this answer out of date? If it is, please let us know via a Comment

Comments

Rohini Thube, July 19, 2017 - 12:39 pm UTC


More to Explore

Analytics

Analytic SQL got you confused? Check out Connor McDonald's complete video course.