如何在 Oracle 11g 中使用 group by 和 pivot
Posted
技术标签:
【中文标题】如何在 Oracle 11g 中使用 group by 和 pivot【英文标题】:How to use group by with pivot in Oracle 11g 【发布时间】:2016-04-12 16:34:07 【问题描述】:表结构
CREATE TABLE PLAN
(
plan_id NUMERIC,
startdate DATE NOT NULL,
enddate DATE,
cost NUMERIC (3) NOT NULL,
plan_type VARCHAR (5) NOT NULL,
CONSTRAINT plan_pk PRIMARY KEY (plan_id),
CONSTRAINT plan_ck CHECK (startdate <= enddate)
);
要求:
创建一个数据透视表,按计划类型(语音、文本、数据)以及成本范围列出计划数量。对于成本范围,创建 3 个部分,“经济计划”定义为月费低于 40 美元的计划,“标准计划”定义为月费在 40 美元到 50 美元之间的计划,以及“高级计划”定义为月费超过 40 美元的计划50 美元。数据透视表结果应包括 3 列(语音、数据、文本)和 3 行(经济计划、标准计划、高级计划)。单元格应包含每个单元格的计数,并且在没有匹配计划的情况下应为 0 而不是 NULL。
我的查询到目前为止
SELECT * FROM
(SELECT cost, plan_type
FROM plan)
PIVOT ( count(plan_type) FOR plan_type IN ('voice', 'data', 'text')
);
它返回所有成本的语音、数据、文本类型计划的计数。我无法在要求中指定的范围内得到它。
我的其他尝试
SELECT CASE
WHEN cost < 40 THEN '1-40'
WHEN cost<=50 THEN '40-50'
ELSE '50+'
END AS cost, count('voice'), count('data'), count('text') FROM
(SELECT cost, plan_type
FROM plan)
PIVOT (
count(plan_type) FOR plan_type IN ('voice', 'data', 'text')
)
GROUP BY CASE
WHEN cost < 40 THEN '1-40'
WHEN cost<=50 THEN '40-50'
ELSE '50+'
END;
此查询甚至将数据透视表中的 0 值计为 1,从而返回错误的答案。请建议我应该如何处理它?
【问题讨论】:
【参考方案1】:如果你把这两种尝试结合起来,你就快到了:
SELECT * FROM (
SELECT case
when cost < 40 then 'Economy Plans'
when cost <= 50 then 'Standard Plans'
else 'Premium Plans'
end as cost_range,
plan_type
FROM plan
)
PIVOT (
count(plan_type) FOR plan_type IN ('voice' as voice, 'data' as data, 'text' as text)
);
子查询为范围分配一个文本标签,然后根据该范围而不是实际计划成本进行数据透视。
使用一些虚构的数据,结果如下:
COST_RANGE VOICE DATA TEXT
-------------- ---------- ---------- ----------
Standard Plans 1 3 0
Economy Plans 2 1 1
Premium Plans 3 2 0
【讨论】:
非常感谢。我正在努力解决它。我确实尝试过一次,但我添加了 Group By 并且返回了错误。 ***.com/questions/36600457/…也请尝试回答这个问题以上是关于如何在 Oracle 11g 中使用 group by 和 pivot的主要内容,如果未能解决你的问题,请参考以下文章
如何为 Oracle 11g 中分层表的每条记录分配父组 ID?
Oracle11g添加asm磁盘到asm磁盘组,发现添加错误如何删除新添加到磁盘?