11g: SQL Pivot
Posted by Tyler Muth on September 18, 2007
Just wanted to post a quick example of the new 11g SQL Pivot syntax (documented here).
Here’s the old pivot method (I believe Tom Kyte invented this one):
select sum("10") "10",sum("20") "20",
sum("30") "30",sum("40") "40",
sum("50") "50",sum("60") "60",
sum("70") "70",sum("80") "80",
sum("90") "90",sum("100") "100",
sum("110") "110"
from(
select max(decode(department_id,10,salary,null)) "10",
max(decode(department_id,20,salary,null)) "20",
max(decode(department_id,30,salary,null)) "30",
max(decode(department_id,40,salary,null)) "40",
max(decode(department_id,50,salary,null)) "50",
max(decode(department_id,60,salary,null)) "60",
max(decode(department_id,70,salary,null)) "70",
max(decode(department_id,80,salary,null)) "80",
max(decode(department_id,90,salary,null)) "90",
max(decode(department_id,100,salary,null)) "100",
max(decode(department_id,110,salary,null)) "110"
from employees
group by department_id);
It’s a very effective method that I’ve used many times, but the syntax is a bit clunky.
And now, the 11g Pivot syntax:
select *
from (select department_id,sum(salary) salary
from employees
where department_id > 0
group by department_id)
pivot (sum(salary)
for department_id in (10,20,30,40,50,60,70,80,90,100,110));
10 20 30 40 50 60 70 80 90 100 110
------ ------ ------ ------ ------ ------ ------ ------- ------ ------ ------
4400 19000 24900 6500 156400 28800 10000 319500 58000 51600 20300
1 rows selected
November 12, 2007 at 11:24 pm
I saw at least 10 web sites talking about 11g features …. I did not see this before. To be honest, this is NUMBER ONE for all data warehouse analysts. It’s so simple to create transposed query using this, I cannot believe they did not do it before.
There was only one feature I liked on MS ACCESS for years, it was transposed queries. Finally I can get it in ORACLE.
thank you for this post
jiri
April 17, 2008 at 7:01 am
GOOD
May 1, 2008 at 9:31 am
Is an excellent feature.
What would make it better is if the IN statement could contain another SELECT rather than just literals.
May 1, 2008 at 10:11 am
If the IN statement were a select instead of literals, then the columns could not be determined at parse time. This would implicitly make the statement Dynamic SQL. However, you could explicitly write this as Dynamic SQL.