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

Oracle Dynamic Pivoting

Die Verwendung von dynamischem SQL für ein Ergebnis, bei dem die Spalten zum Zeitpunkt der Ausführung unbekannt sind, ist in Oracle im Vergleich zu bestimmten anderen RDMBS etwas umständlich.

Da der Satztyp für die Ausgabe noch unbekannt ist, kann er nicht vorher definiert werden.

In Oracle 11g besteht eine Möglichkeit darin, eine namenlose Prozedur zu verwenden, die eine temporäre Tabelle mit dem Pivot-Ergebnis generiert.

Wählen Sie dann die Ergebnisse aus dieser temporären Tabelle aus.

declare
  v_sqlqry clob;
  v_cols clob;
begin
  -- Generating a string with a list of the unique names
  select listagg(''''||CCL||''' as "'||CCL||'"', ', ') within group (order by CCL)
  into v_cols
  from 
  (
    select distinct CCL
    from tableA
  );

  -- drop the temporary table if it exists
  EXECUTE IMMEDIATE 'DROP TABLE tmpPivotTableA';
  EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;

  -- A dynamic SQL to create a temporary table 
  -- based on the results of the pivot
  v_sqlqry := '
    CREATE GLOBAL TEMPORARY TABLE tmpPivotTableA
    ON COMMIT PRESERVE ROWS AS
    SELECT * 
    FROM (SELECT ID, CCL, Flag FROM TableA) src 
    PIVOT (MAX(Flag) FOR (CCL) IN ('||v_cols||')) pvt';

  -- dbms_output.Put_line(v_sqlqry); -- just to check how the sql looks like
  execute immediate v_sqlqry;

end;
/

select * from tmpPivotTableA;

Rückgabe:

ID  adam john rob terry
--  ---- ---- --- -----
1   x    x    x
2        x      

Einen Test zu db<>fiddle finden Sie hier

In Oracle 11g findet sich in diesem Blog ein weiterer cooler Trick (erstellt von Anton Scheffer), der verwendet werden kann. Aber Sie müssen dafür die Pivot-Funktion hinzufügen.
Der Quellcode befindet sich in diesem Zip

Danach kann das SQL so einfach sein:

select * from 
table(pivot('SELECT ID, CCL, Flag FROM TableA'));

Einen Test zu db<>fiddle finden Sie hier