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

Créer une vue Pivot en SQL à partir d'une table SQL

Une fonction stockée(ou procédure ) peut être créé afin de créer un SQL pour le pivotement dynamique, et le jeu de résultats est chargé dans une variable de type SYS_REFCURSOR :

CREATE OR REPLACE FUNCTION Get_Categories_RS RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_cols_1    VARCHAR2(32767);
  v_cols_2    VARCHAR2(32767);  
BEGIN
  SELECT LISTAGG( ''''||"level"||''' AS "'||"level"||'"' , ',' )
          WITHIN GROUP ( ORDER BY "level" DESC )
    INTO v_cols_1
    FROM (
          SELECT DISTINCT "level"
            FROM temp
          );

  SELECT LISTAGG( 'MAX(CASE WHEN category = '''||category||''' THEN "'||"level"||'" END) AS "'||"level"||'_'||category||'"' , ',' )
          WITHIN GROUP ( ORDER BY category, "level" DESC )
    INTO v_cols_2
    FROM (
          SELECT DISTINCT "level", category
            FROM temp
          );

  v_sql :=
  'SELECT "set", '|| v_cols_2 ||'
     FROM
     (
      SELECT *
        FROM temp
       PIVOT
       (
        MAX(value) FOR "level" IN ( '|| v_cols_1 ||' )
       )
      )
      GROUP BY "set"
      ORDER BY "set"'; 

  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;

dans lequel j'ai utilisé deux niveaux de pivotement :le premier est dans la requête interne impliquant PIVOT Clause, et la seconde se trouve dans la requête externe ayant la logique d'agrégation conditionnelle. Notez que l'ordre des niveaux doit être dans l'ordre décroissant (Z , Y , X ) dans le résultat attendu comme étant conforme à la description.

Et ensuite invoquer

VAR rc REFCURSOR
EXEC :rc := Get_Categories_RS;
PRINT rc

à partir de la ligne de commande du développeur SQL afin d'obtenir le jeu de résultats

Au fait, évitez d'utiliser des mots-clés réservés tels que set et level comme dans ton cas. J'avais besoin de les citer pour pouvoir les utiliser.