Oracle
 sql >> Database >  >> RDS >> Oracle

Pivoting dinamico Oracle

L'uso di sql dinamico per un risultato in cui le colonne sono sconosciute al momento dell'esecuzione è un po' una seccatura in Oracle rispetto ad altri RDMBS.

Poiché il tipo di record per l'output è ancora sconosciuto, non può essere definito in anticipo.

In Oracle 11g, un modo consiste nell'utilizzare una procedura senza nome che genera una tabella temporanea con il risultato ruotato.

Quindi seleziona i risultati da quella tabella temporanea.

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;

Resi:

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

Puoi trovare un test su db<>violino qui

In Oracle 11g, un altro fantastico trucco (creato da Anton Scheffer) da utilizzare può essere trovato in questo blog. Ma dovrai aggiungere la funzione pivot.
Il codice sorgente può essere trovato in questo zip

Dopodiché l'SQL può essere semplice come questo:

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

Troverai un test su db<>violino qui