Oracle如何汇总多个计数字段

时间:2018-07-09 08:38:00

标签: oracle count sum

我有以下选择语句:

SELECT 1 AS SoftField, 
       count(form_ref) as Asset
 from risk_register 
where risk_category = 'fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1' 
  and system_type = 'AR'
UNION
SELECT 2 AS SoftField,
       count(form_ref)as Operational
from risk_register 
where risk_category = '42a476db-0b3d-4375-9eba-5051d3a2507e' 
  and system_type = 'AR'

输出:

Softfield   Asset 
---------   -----
1           1180
2           2927

我如何将资产总结如下:

Softfield   Asset 
---------   -----
1           1180
2           2927
Total       4107

2 个答案:

答案 0 :(得分:3)

您可以使用group by rollup生成“超级聚合”行:

-- CTE for your sample data
with risk_register (system_type, risk_category, form_ref) as (
  select 'AR', 'fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1', 'x'
  from dual connect by level <= 1180
  union all
  select 'AR', '42a476db-0b3d-4375-9eba-5051d3a2507e', 'x'
  from dual connect by level <= 2927
)
-- actual query
select case risk_category when 'fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1' then '1'
                          when '42a476db-0b3d-4375-9eba-5051d3a2507e' then '2'
                          else 'Total' end as softfield,
count(form_ref) as asset
from risk_register
where risk_category in ('fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1',
                        '42a476db-0b3d-4375-9eba-5051d3a2507e')
and system_type = 'AR'
group by rollup(risk_category)
order by softfield;

SOFTFIELD      ASSET
--------- ----------
1               1180
2               2927
Total           4107

这是通过一个字符串字段排序的,该字符串字段(仅)可以使用这些值,但是如果您使用的值大于9,那么它将变得有点奇怪,并且您需要使其变得更加复杂。


@NickKrasnov在评论中链接到简化版本,该注释将“ softfield”按类别的字母顺序排列。您的原始查询具有与您提供要搜索的值的顺序匹配的查询。尚不清楚这是否重要,因为无论如何,软域值似乎有些武断。保持原始订单而不重复值的另一种方法是使用集合(保持Nick对grouping()的使用):

select case when grouping(coll.risk_category) = 1 then 'Total' 
            else to_char(max(coll.rn)) end as softfield,
  count(rr.form_ref) as asset
from (
  select rownum as rn, column_value as risk_category
  from table(sys.odcivarchar2list('fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1',
                                  '42a476db-0b3d-4375-9eba-5051d3a2507e'))
) coll
join risk_register rr
on rr.risk_category = coll.risk_category
where system_type = 'AR'
group by rollup(coll.risk_category)
order by grouping(coll.risk_category), max(coll.rn);

如果顺序无关紧要,或者您想查看更简单的实际类别:

select case when grouping(risk_category) = 1 then 'Total' 
            else risk_category end as softfield,
  count(form_ref) as asset
from risk_register
where risk_category in ('fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1',
                        '42a476db-0b3d-4375-9eba-5051d3a2507e')
and system_type = 'AR'
group by rollup(risk_category)
order by grouping(risk_category), risk_category;

甚至

select nvl(risk_category, 'Total') as softfield,
  count(form_ref) as asset
...

答案 1 :(得分:1)

您可以将cte与WITH一起使用,然后使用两次查询:

With cte as (
  SELECT 1 AS SoftField, 
  count(form_ref) as Asset
  from risk_register 
  where risk_category = 'fdbb8c65-cb78-4e9b-bfb7-d96a9d0b01b1' and system_type = 'AR'
  UNION
  SELECT 2 AS SoftField,
  count(form_ref)as Operational
  from risk_register 
  where risk_category = '42a476db-0b3d-4375-9eba-5051d3a2507e' and system_type = 'AR'
)
select * from cte
union all
select 'TOTAL', sum(asset) 
from cte

另一种选择使用ROLLUP

select nvl(SoftField,'TOTAL') SoftField,
       sum(asset) Asset
from cte
group by rollup(SoftField)