sql >> Databasteknik >  >> RDS >> Oracle

UNPIVOT på ett obestämt antal kolumner

Det låter som att du vill avpivotera tabellen (pivotering skulle innebära att gå från många rader och 2 kolumner till 1 rad med många kolumner). Du skulle troligen behöva använda dynamisk SQL för att generera frågan och sedan använda DBMS_SQL paket (eller eventuellt EXECUTE IMMEDIATE ) för att utföra det. Du bör också kunna konstruera en pipelined tabellfunktion som gjorde unpivoteringen. Du skulle behöva använda dynamisk SQL i pipelined tabellfunktionen också, men det skulle potentiellt vara mindre kod. Jag förväntar mig en ren dynamisk SQL-sats som använder UNPIVOT för att vara effektivare.

Ett ineffektivt tillvägagångssätt, men ett som är relativt lätt att följa, skulle vara något liknande

SQL> ed
Wrote file afiedt.buf

  1  create or replace type emp_unpivot_type
  2  as object (
  3    empno number,
  4    col   varchar2(4000)
  5* );
SQL> /

Type created.

SQL> create or replace type emp_unpivot_tbl
  2  as table of emp_unpivot_type;
  3  /

Type created.

SQL> ed
Wrote file afiedt.buf

  1  create or replace function unpivot_emp
  2  ( p_empno in number )
  3    return emp_unpivot_tbl
  4    pipelined
  5  is
  6    l_val varchar2(4000);
  7  begin
  8    for cols in (select column_name from user_tab_columns where table_name = 'EMP')
  9    loop
 10      execute immediate 'select ' || cols.column_name || ' from emp where empno = :empno'
 11         into l_val
 12       using p_empno;
 13      pipe row( emp_unpivot_type( p_empno, l_val ));
 14    end loop;
 15    return;
 16* end;
SQL> /

Function created.

Du kan sedan anropa det i en SQL-sats (jag skulle tro att du skulle vilja ha åtminstone en tredje kolumn med kolumnnamnet)

SQL> ed
Wrote file afiedt.buf

  1  select *
  2*   from table( unpivot_emp( 7934 ))
SQL> /

     EMPNO COL
---------- ----------------------------------------
      7934 7934
      7934 MILLER
      7934 CLERK
      7934 7782
      7934 23-JAN-82
      7934 1301
      7934
      7934 10

8 rows selected.

Ett mer effektivt tillvägagångssätt skulle vara att anpassa Tom Kytes pipelined-tabellfunktion för show_table.




  1. Hämta DB-ägarens namn i PostgreSql

  2. Hur DATE_SUB() fungerar i MariaDB

  3. implementera LIKE-fråga i PDO

  4. android.database.CursorIndexOutOfBoundsException