Oracle
 sql >> Datenbank >  >> RDS >> Oracle

oracle :Dynamischer Spaltenname

Da Sie Oracle10g verwenden, gibt es kein PIVOT Funktion, also müssen Sie diese Art von Transformation mit einer Aggregatfunktion mit einem CASE durchführen Aussage.

Wenn die Werte im Voraus bekannt sind, können Sie sie in einer statischen Version fest codieren:

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

Siehe SQL-Fiddle mit Demo

Wenn Ihre Werte jedoch nicht im Voraus bekannt sind, müssen Sie dynamisches SQL implementieren, und in Oracle möchten Sie dafür eine Prozedur verwenden:

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;
/

Um dann die Ergebnisse zurückzugeben, können Sie (Hinweis: so mache ich es in Toad):

variable x refcursor
exec dynamic_pivot(:x)
print x

Beide geben das Ergebnis zurück:

| TS_LOCATION | APPLE | MANGO | PINEAPPLE |
-------------------------------------------
|          LN |     0 |    10 |        35 |
|          QL |    25 |     0 |        20 |
|          NY |   100 |     5 |        50 |