Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

oráculo:nome da coluna dinâmica


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 |