Oracle
 sql >> база данни >  >> RDS >> Oracle

Pivot с динамични колони в Oracle

SYS_REFCURSOR в рамките на съхранена функция (напр. PL/SQL, използван вместо директно използване на SQL ) може да се използва за получаване на динамично генериран набор от резултати (напр. Dynamic Pivot ). В този случай се генерира низ за условно агрегиране:

CREATE OR REPLACE FUNCTION get_passengers_rs RETURN SYS_REFCURSOR IS
  v_recordset SYS_REFCURSOR;
  v_sql       VARCHAR2(32767);
  v_str       VARCHAR2(32767);
BEGIN
  SELECT LISTAGG('MAX(CASE WHEN rn = '||lvl||' THEN age||''(''||passengers||'')'' END) 
                   AS "Age'||lvl||'"' ,',') WITHIN GROUP (ORDER BY 0)
    INTO v_str
    FROM ( SELECT level AS lvl  
             FROM dual
          CONNECT BY level <= (SELECT MAX(COUNT(*)) FROM t GROUP BY ID ) ) t;  

  v_sql :=
  'SELECT ID, '|| v_str ||'
     FROM 
     (
      SELECT t.*, 
             ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
        FROM t     
      )
    GROUP BY ID';

  OPEN v_recordset FOR v_sql;
  RETURN v_recordset;
END;

Добавих и имената на пътниците, за да различим добре всяка информация.

След това изпълнете кода по-долу:

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

от командния ред на SQL Developer, за да видите очаквания набор от резултати.

Кодът по-горе генерира този SQL низ (v_sql ) за съществуващите в момента данни

SELECT ID, MAX(CASE WHEN rn = 1 THEN age||'('||passengers||')' END) AS "Age1",
           MAX(CASE WHEN rn = 2 THEN age||'('||passengers||')' END) AS "Age2",
           MAX(CASE WHEN rn = 3 THEN age||'('||passengers||')' END) AS "Age3"
  FROM 
     (
      SELECT t.*, 
             ROW_NUMBER() OVER (PARTITION BY ID ORDER BY 0) AS rn
        FROM t     
      )
 GROUP BY ID

което дава

ID      Age1        Age2            Age3
123456  58(Marie)   65(Ben) 
123458  32(Aaron)   18(Caroline)    37(Stephanie)

като набор от резултати.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Покритие на код за PL/SQL

  2. Как да изберете редове с 4-байтови UTF-8 символи в Oracle DB?

  3. Идентификаторът ORA-00972 е твърде дълго име на колона с псевдоним

  4. Oracle SQL сравнява записи в таблица

  5. Изключение за формат на Oracle Date в услугите за отчитане на SQL Server