Como você está usando Oracle10g, não há
PIVOT
então você terá que realizar esse tipo de transformação usando uma função agregada com um CASE
declaração. Se os valores forem conhecidos com antecedência, você poderá codificá-los em uma versão estática:
select s.ts_location,
sum(case when p.tp_name = 'apple' then s.ts_sales else 0 end) Apple,
sum(case when p.tp_name = 'mango' then s.ts_sales else 0 end) Mango,
sum(case when p.tp_name = 'pineapple' then s.ts_sales else 0 end) Pineapple
from tbl_sales s
inner join tbl_products p
on s.ts_tp_id = p.tp_id
group by s.ts_location
Consulte SQL Fiddle with Demo
Mas se seus valores não forem conhecidos com antecedência, você precisará implementar o sql dinâmico e no Oracle você desejará usar um procedimento para isso:
CREATE OR REPLACE procedure dynamic_pivot(p_cursor in out sys_refcursor)
as
sql_query varchar2(1000) := 'select s.ts_location ';
begin
for x in (select distinct tp_name from tbl_products order by 1)
loop
sql_query := sql_query ||
' , sum(case when p.tp_name = '''||x.tp_name||''' then s.ts_sales end) as '||x.tp_name;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from tbl_sales s
inner join tbl_products p
on s.ts_tp_id = p.tp_id
group by s.ts_location';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
Em seguida, para retornar os resultados, você pode usar (nota: é assim que eu faço no Toad):
variable x refcursor
exec dynamic_pivot(:x)
print x
Ambos retornarão o resultado:
| TS_LOCATION | APPLE | MANGO | PINEAPPLE |
-------------------------------------------
| LN | 0 | 10 | 35 |
| QL | 25 | 0 | 20 |
| NY | 100 | 5 | 50 |