Oracle
 sql >> Base de données >  >> RDS >> Oracle

Pivotement dynamique Oracle

L'utilisation de sql dynamique pour un résultat où les colonnes sont inconnues au moment de l'exécution est un peu compliquée dans Oracle par rapport à certains autres RDMBS.

Étant donné que le type d'enregistrement pour la sortie est encore inconnu, il ne peut pas être défini à l'avance.

Dans Oracle 11g, une façon consiste à utiliser une procédure sans nom qui génère une table temporaire avec le résultat pivoté.

Sélectionnez ensuite les résultats de cette table temporaire.

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;

Renvois :

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

Vous pouvez trouver un test sur db<>violon ici

Dans Oracle 11g, une autre astuce sympa (créée par Anton Scheffer) à utiliser peut être trouvée dans ce blog. Mais vous devrez ajouter la fonction pivot pour cela.
Le code source se trouve dans ce zip

Après cela, le SQL peut être aussi simple que ceci :

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

Vous trouverez un test sur db<>violon ici