基于特定条件的分组和聚合

时间:2017-01-13 14:49:32

标签: oracle oracle11g group-by conditional aggregate-functions

我的查询结果集如下所示

trackingnumber   type         price 
------------------------------------------
12799467         AVRM         674.0536
12799467         AVRM         860.7415
12799467         PRICESTD     200.00
12799468         PRICESTD     590.85
12799469         PRICESTD     800
12799470         PRICESTD     640
12799471         PRICESTD     160
12799472         PRICESTD     2080
12799473         PRICESTD     354.3779

我希望按trackingnumber对此进行分组,如果分组结果集的计数大于1,则返回SUM的所有price type } AVRM否则按原样返回单个价格。如果算了 更多是零,他们都没有type AVRM然后它的总价格将为空

预期的结果将是这个

trackingnumber  Total Price
-----------------------------------------
12799467        1534.7951 --sum of price excluding 200
12799468        590.85
12799469        800
12799470        640
12799471        160
12799472        2080
12799473        354.3779

除了trackingnumber分组,并在type部分使用case语句检查select之外,我想不出办法完成任务我认为不行,因为我们没有按type

分组

我不确定是否可以使用单个查询来实现。

2 个答案:

答案 0 :(得分:3)

是的,可以在一个查询中完成。

with sample_data ( tracking_Number, "TYPE", price ) as
(  
SELECT 12799467,'AVRM',674.0536 FROM DUAL UNION ALL
SELECT 12799467,'AVRM',860.7415 FROM DUAL UNION ALL
SELECT 12799467,'PRICESTD',200.00 FROM DUAL UNION ALL
SELECT 12799468,'PRICESTD',590.85 FROM DUAL UNION ALL
SELECT 12799469,'PRICESTD',800 FROM DUAL UNION ALL
SELECT 12799470,'PRICESTD',640 FROM DUAL UNION ALL
SELECT 12799471,'PRICESTD',160 FROM DUAL UNION ALL
SELECT 12799472,'PRICESTD',2080 FROM DUAL UNION ALL
SELECT 12799473,'PRICESTD',354.3779 FROM DUAL )
SELECT tracking_number, 
       case when count(*) > 1 THEN 
          sum(decode("TYPE",'AVRM',price,null)) ELSE 
          sum(price) END price
from sample_data
group by tracking_number
order by tracking_Number;

答案 1 :(得分:0)

例如下一个解决方案。我添加条件以排除类型不等于' AVRM'如果行包含' AVRM'施放

with s (trackingnumber ,type        ,price)
as (
select 12799467,'AVRM',674.0536 from dual union all
select 12799467        ,'AVRM',         860.7415  from dual union all
select 12799467        ,'PRICESTD',     200.00  from dual union all
select 12799468         ,'PRICESTD',       590.85  from dual union all
select 12799469         ,'PRICESTD',       800  from dual union all
select 12799470         ,'PRICESTD',       640  from dual union all
select 12799471         ,'PRICESTD',       160  from dual union all
select 12799472         ,'PRICESTD',       2080  from dual union all
select 12799473         ,'PRICESTD',       354.3779  from dual )
select trackingnumber, 
       sum(price)
 from (select s.*,rownum as rn from s
        where not exists (select null
                        from s subs
                where s.trackingnumber = subs.trackingnumber
                  and s.type != 'AVRM'
                  and subs.type = 'AVRM')
       )
 group by trackingnumber,
          case when type = 'AVRM' then 0 else rn end;