代码之家  ›  专栏  ›  技术社区  ›  stack0114106

当多个条件满足时,如何分组计算平均值

  •  2
  • stack0114106  · 技术社区  · 6 年前

    我正在使用Oracle数据库,想计算不同地区的平均产品价格。

    例子:

    prod,amt,price
    X,100,1
    X,180,2
    X,250,3
    Y,90,2
    Y,170,3
    Y,280,3
    

    这里,产品X在一个地区以100元出售,在另一个地区以180元出售等等。

    现在,对于一些分析来说,它们被分为不同的重叠范围,我需要根据范围计算出价格的平均值。

    所需输出为

    prod,rang(Amt),mean(price),
    X,[0-200],1.5,
    X,[150-300],2.5,
    Y,[0-200],2.5,
    Y,[150-300],3,
    

    请注意,有许多范围,为了清晰起见,我只给出了2个范围。

    我试过像下面那样,但是 case 匹配第一个条件,只为[0-200]的x提供一个值,我需要2条记录

    select prod, amt, price, 
    case 
    when amt between 0 and 200 then amt
    when amt between 150 and 300 then amt
    end as rng
    from tablea
    

    在case语句中如何获取匹配的2条记录?.

    2 回复  |  直到 6 年前
        1
  •  2
  •   Barbaros Özhan    6 年前

    你可以使用 conditional aggregation 然后 unpivot 作为

       select prod_a as "Prod",
              prod as "Range of Amounts",
              value as "Mean Price"
         from  
                (
                with tablea(prod,amt,price) as
                (
                  select 'X',100,1 from dual union all
                  select 'X',180,2 from dual union all
                  select 'X',250,3 from dual union all
                  select 'Y',90, 2 from dual union all
                  select 'Y',170,3 from dual union all
                  select 'Y',280,3 from dual 
                )
                select prod as prod_a,  
                avg(case when amt between 0 and 200 then price end) as avg_0_200,
                avg(case when amt between 150 and 300 then price end) as avg_150_300
                from tablea a
                group by prod
                 ) b  
        unpivot(value for prod in(avg_0_200,avg_150_300))
        order by prod_a;
    
       Prod  Range of Amounts   Mean Price
       ----  ----------------    ----------
       X     AVG_0_200              1.5
       X     AVG_150_300            2.5
       Y     AVG_0_200              2.5
       Y     AVG_150_300            3
    

    Rextester Demo

        2
  •  1
  •   MT0    6 年前

    使用单个条件进行两个查询,并将它们联合起来。这不是一个完美的解决方案,但会奏效。

    SELECT prod, '0-200' rang, AVG( price )
    FROM   table_name
    WHERE  amt BETWEEN 0 AND 200
    GROUP BY prod
    UNION ALL
    SELECT prod, '150-300' rang, AVG( price )
    FROM   table_name
    WHERE  amt BETWEEN 150 AND 300
    GROUP BY prod