Ponieważ używasz Oracle10g, nie ma PIVOT
funkcji, więc będziesz musiał wykonać tego typu przekształcenie za pomocą funkcji agregującej z CASE
oświadczenie.
Jeśli wartości są znane z wyprzedzeniem, możesz je na stałe zakodować w wersji statycznej:
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
Zobacz SQL Fiddle z wersją demonstracyjną
Ale jeśli twoje wartości nie są znane z wyprzedzeniem, musisz zaimplementować dynamiczny sql, a w Oracle będziesz chciał użyć do tego procedury:
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;
/
Następnie, aby zwrócić wyniki, których możesz użyć (uwaga: tak to robię w Toad):
variable x refcursor
exec dynamic_pivot(:x)
print x
Oba zwrócą wynik:
| TS_LOCATION | APPLE | MANGO | PINEAPPLE |
-------------------------------------------
| LN | 0 | 10 | 35 |
| QL | 25 | 0 | 20 |
| NY | 100 | 5 | 50 |