在Single语句中获取多个聚合

时间:2012-09-05 20:52:05

标签: oracle plsql

该表包含城市及其分支/ atms的数据

CITY        TYPE       NAME
 ----------------------------------
 agra         atm         X
 agra         branch      X1 
 delhi        atm         X2
 agra         atm         X3
 agra         atm         X4
 delhi        branch      X5
 chennai      branch      X6

预期的结果集是

CITY     ATM   BRANCH
------------------------------------
agra       3       1 
delhi      1       1
chennai    0       1

我们是否可以在一个选择语句中执行此操作。

3 个答案:

答案 0 :(得分:5)

您可以使用聚合中的条件求和来执行此操作:

select t.city,
       sum(case when type = 'atm' then 1 else 0 end) as ATM,
       sum(case when type = 'branch' then 1 else 0 end) as branch
from t
group by t.city

答案 1 :(得分:1)

如果事先知道列的所有值,那么您可以在查询中对它们进行硬编码。否则会变得更加复杂。这是在Oracle SQL中:

with my_data as
    (select 'agra' city, 'atm' "type", 'X' "name" from dual union
    select 'agra' city, 'branch' "type", 'X1' "name" from dual union
    select 'delhi' city, 'atm' "type", 'X2' "name" from dual union
    select 'agra' city, 'atm' "type", 'X3' "name" from dual union
    select 'agra' city, 'atm' "type", 'X4' "name" from dual union
    select 'delhi' city, 'branch' "type", 'X5' "name" from dual union
    select 'chennai' city, 'branch' "type", 'X6' "name" from dual)

select city,
    sum(decode("type", 'atm', 1, 0)) as ATM,
    sum(decode("type", 'branch', 1, 0)) as branch
from my_data
group by city;

如果列数未知,Oracle会有一个“PIVOT XML”语句,允许它在一个XML中返回所有汇总数据:

select * from my_data
PIVOT XML (count("name") for "type" in (ANY));

您可以使用EXTRACTVALUE()函数自行解析每个列,但这仍然意味着您需要提前知道有多少列。我相信Oracle SQL无法创建具有动态列数的数据透视表。它可以在PL / SQL中完成,您可以使用游标动态连接SQL。

答案 2 :(得分:0)

这是您应该在MS Access中执行的操作:

TRANSFORM Count(Table1.Name) AS CountOfName
SELECT Table1.City
FROM Table1
GROUP BY Table1.City
PIVOT Table1.Type;

我猜PLSQL并没有那么不同,它也有“pivot”子句可用

修改

使用pivot

在PL / SQL中
select * from (
    SELECT city, type FROM t ) 
       PIVOT(count(*)  for (type) in ('atm', 'branch'));