Oracle按每个聚合函数的不同条件分组

时间:2019-01-03 07:52:20

标签: sql oracle group-by aggregate-functions

我想知道是否可以执行分组依据,并为每个聚集函数选择不同的行子集。 示例:

select order, count(*), sum(*), avg(*)
from table_orders
group by order

我想使用不同的条件来限制每个聚集函数使用的行,例如

count(*) where order_price > 100
sum(*) where order_id < 200
avg(*) where other_condition

谢谢大家!

3 个答案:

答案 0 :(得分:2)

您可以尝试以下操作-使用case when表达式

select order, count(case when  order_price > 100 then order end), 
sum(case when order_id < 200 then order_price end), 
avg(case when other condition then order_price end)
from table_orders
group by order

答案 1 :(得分:1)

假设您具有以下ORDERS表:

create table orders ( id, order_price )
as
select level, level * 100
from dual
connect by level <= 12 ;


ID  ORDER_PRICE  
1   100          
2   200          
3   300          
4   400          
5   500          
6   600          
7   700          
8   800          
9   900          
10  1000         
11  1100         
12  1200 

使用CASE ...(如@ fa06建议)将为您提供以下结果-可能与您最初想要的不一样:

--
-- eg 
-- {1} count orders that have an order_price greater than 500
-- {2} find the sum of all orders that have an order_price greater than 900
-- {3} find the average value of orders that have an order_price < 300 
--
select 
  id
, count( case when order_price > 500 then id end )         count_
, sum( case when order_price > 900 then order_price end )  sum_
, avg( case when order_price < 300 then order_price end )  avg_
from orders
group by id
;

-- result
ID  COUNT_  SUM_  AVG_  
1   0       NULL  100   
6   1       NULL  NULL  
11  1       1100  NULL  
2   0       NULL  200   
4   0       NULL  NULL  
5   0       NULL  NULL  
8   1       NULL  NULL  
3   0       NULL  NULL  
7   1       NULL  NULL  
9   1       NULL  NULL  
10  1       1000  NULL  
12  1       1200  NULL  

12 rows selected.

您可以在嵌入式视图中使用CASE,并按如下方式汇总其结果集:

select 
  count( gt500 )
, sum ( gt900 )
, avg ( lt300 )
from (
  select 
    id
  , case when order_price > 500 then 1 end            gt500
  , case when order_price > 900 then order_price end  gt900
  , case when order_price < 300 then order_price end  lt300
  from orders
)
;

-- result
COUNT(GT500)  SUM(GT900)  AVG(LT300)  
7             3300        150  

答案 2 :(得分:0)

这样的事情会满足您的需求吗?

SQL> select e.deptno,
  2    (select count(*)
  3     from emp e1
  4     where e1.job = 'SALESMAN'
  5       and e1.deptno = e.deptno
  6    ) v_count,
  7    (select sum(e2.sal)
  8     from emp e2
  9     where e2.comm is not null
 10       and e2.deptno = e.deptno
 11    ) v_sum,
 12    (select round(avg(e3.sal))
 13     from emp e3
 14     where e3.ename < 'KING'
 15       and e3.deptno = e.deptno
 16    ) v_avg
 17  from emp e
 18  group by e.deptno;

    DEPTNO    V_COUNT      V_SUM      V_AVG
---------- ---------- ---------- ----------
        30          4       5600       1800
        20          0        800       2358
        10          0                  2450

SQL>