问题
update: what I was calling coalesce I should have been calling pivot.
I'm extracting some daily usage counts from a log table. I can easily get this data one row per date/item, but I would like to pivot coalesce the columns into a single row.
e.g., I have:
date item-to-be-counted count-of-item
10/1 foo 23
10/1 bar 45
10/2 foo 67
10/2 bar 89
I want:
date count-of-foo count-of-bar
10/1 23 45
10/2 67 89
Here's my current 10g query.
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
update: 11g has a pivot operation. The accepted answer shows how to do this in 9i and 10g.
回答1:
What you're looking for is pivoting - transposing the row data into columnar.
Oracle 9i+, Using WITH/CTE:
Use:
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
Non-WITH/CTE Equivalent
Use:
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
Pre Oracle9i would need the CASE statements changed to DECODE, Oracle specific IF/ELSE logic.
Oracle 11g+, Using PIVOT
Untested:
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
回答2:
Well, I can at least provide an 11 solution; use Pivot:
http://www.oracle.com/technology/pub/articles/oracle-database-11g-top-features/11g-pivot.html
The only 10g option I can think of offhand (I'm decent with SQL, but not an expert) is to fill a table variable and then select individual rows out of that table for your final result. Ugly and likely fairly slow, but could get the job done.
来源:https://stackoverflow.com/questions/2169720/oracle-pivot-coalesce-some-counts-onto-a-single-row