-1

该表包含城市及其分支机构/自动取款机的数据

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

我们是否可以在一个 select 语句中做到这一点。

4

3 回答 3

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
于 2012-09-05T21:37:29.143 回答
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。

于 2012-09-05T21:30:51.647 回答
0

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

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

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

编辑

在 PL/SQL 中使用数据透视

select * from (
    SELECT city, type FROM t ) 
       PIVOT(count(*)  for (type) in ('atm', 'branch'));
于 2012-09-05T21:11:18.863 回答