更新:我正在调用的内容合并我应该一直在调用 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中执行此操作。
答案 0 :(得分:4)
您正在寻找的是旋转 - 将行数据转换为柱状。
使用:
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
使用:
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逻辑。
未测试:
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 :(得分:0)
好吧,我至少可以提供11解决方案;使用Pivot:
http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html
我能想到的唯一10g选项(我对SQL很好,但不是专家)是填充表变量,然后从该表中选择单个行以获得最终结果。丑陋且可能相当慢,但可以完成工作。