Oracle:将一些计数旋转(合并)到单行?
Posted
技术标签:
【中文标题】Oracle:将一些计数旋转(合并)到单行?【英文标题】:Oracle: pivot (coalesce) some counts onto a single row? 【发布时间】:2010-01-30 22:33:02 【问题描述】:更新:我之前调用的是 coalesce 我应该调用的是 pivot。
我正在从日志表中提取一些日常使用计数。我可以轻松地为每个日期/项目获取一行数据,但我想将 coalesce 列转换为一行。
例如,我有:
date item-to-be-counted count-of-item
10/1 foo 23
10/1 bar 45
10/2 foo 67
10/2 bar 89
我想要:
date count-of-foo count-of-bar
10/1 23 45
10/2 67 89
这是我当前的 10g 查询。
select trunc(started,'HH'),depot,count(*)
from logstats
group by trunc(started,'HH'),depot
order by trunc(started,'HH'),depot;
TRUNC(STARTED,'HH') DEPOT COUNT(*)
------------------------- ---------- --------
10/01/11 01.00.00 foo 28092
10/01/11 01.00.00 bar 2194
10/01/11 02.00.00 foo 3402
10/01/11 02.00.00 bar 1058
更新:11g 有一个 pivot 操作。接受的答案显示了如何在 9i 和 10g 中执行此操作。
【问题讨论】:
【参考方案1】:您正在寻找的是旋转 - 将行数据转换为柱状数据。
Oracle 9i+,使用 WITH/CTE:
用途:
WITH summary AS (
SELECT TRUNC(ls.started,'HH') AS dt,
ls.depot,
COUNT(*) AS num_depot
FROM logstats ls
GROUP BY TRUNC(ls.started,'HH'), ls.depot)
SELECT s.dt,
MAX(CASE WHEN s.depot = 'foo' THEN s.num_depot ELSE 0 END) AS "count_of_foo",
MAX(CASE WHEN s.depot = 'bar' THEN s.num_depot ELSE 0 END) AS "count_of_bar"
FROM summary s
GROUP BY s.dt
ORDER BY s.dt
非 WITH/CTE 等效项
用途:
SELECT s.dt,
MAX(CASE WHEN s.depot = 'foo' THEN s.num_depot ELSE 0 END) AS "count_of_foo",
MAX(CASE WHEN s.depot = 'bar' THEN s.num_depot ELSE 0 END) AS "count_of_bar"
FROM (SELECT TRUNC(ls.started,'HH') AS dt,
ls.depot,
COUNT(*) AS num_depot
FROM LOGSTATS ls
GROUP BY TRUNC(ls.started, 'HH'), ls.depot) s
GROUP BY s.dt
ORDER BY s.dt
Oracle9i 之前需要将 CASE
语句更改为 DECODE
,Oracle 特定的 IF/ELSE 逻辑。
Oracle 11g+,使用 PIVOT
未经测试:
SELECT *
FROM (SELECT TRUNC(ls.started, 'HH') AS dt,
ls.depot
FROM LOGSTATS ls
GROUP BY TRUNC(ls.started, 'HH'), ls.depot)
PIVOT (
COUNT(*) FOR depot
)
ORDER BY 1
【讨论】:
您介意仔细检查示例 1 吗?我修复了 "as" 引用,但在最后一行得到 ORA-00904: "SUMMARY"."DT": invalid identifier。谢谢! 使用单引号并且没有AS
关键字是接受的列别名语法。使用双引号的唯一原因是为了支持特殊字符。它在 PLSQL Developer 中按原样工作,但我有回应说 Toad 和 DBVisualizer 不喜欢单引号方法。
hmm,我也在使用 sqldeveloper... 加上它给出的单引号 >,改为双引号可以解决这些问题。这个10g。
在 9i 和 10g、PLSQL Developer 6 和 7 中使用单引号没有问题。
嗯,它不适用于 sqlplus。此外,在原版中,FROM 之前还有一个额外的逗号。我会将我的编辑恢复为您的示例,并留下我得到的结果。我会用谷歌搜索“10g pivot”,看看我能不能弄清楚。谢谢指点!【参考方案2】:
好吧,我至少可以提供 11 个解决方案;使用枢轴:
http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html
我能临时想到的唯一 10g 选项(我很擅长 SQL,但不是专家)是填充表变量,然后从该表中选择单个行以获得最终结果。丑陋,可能相当慢,但可以完成工作。
【讨论】:
以上是关于Oracle:将一些计数旋转(合并)到单行?的主要内容,如果未能解决你的问题,请参考以下文章
Oracle APEX 交互式报告中的错误 - ORA-01427:单行子查询返回多于一行