sql >> Database >  >> RDS >> Oracle

UNPIVOT op een onbepaald aantal kolommen

Het klinkt alsof u de draaiing van de tabel ongedaan wilt maken (draaien zou betekenen dat u van veel rijen en 2 kolommen naar 1 rij met veel kolommen gaat). U zou hoogstwaarschijnlijk dynamische SQL moeten gebruiken om de query te genereren en vervolgens de DBMS_SQL pakket (of mogelijk EXECUTE IMMEDIATE ) om het uit te voeren. Je zou ook in staat moeten zijn om een ​​pijplijn-tabelfunctie te construeren die het draaien ongedaan heeft gemaakt. Je zou ook dynamische SQL moeten gebruiken binnen de pijplijntabelfunctie, maar het zou mogelijk minder code zijn. Ik zou een pure dynamische SQL-instructie verwachten met behulp van UNPIVOT om echter efficiënter te zijn.

Een inefficiënte aanpak, maar wel een die relatief gemakkelijk te volgen is, zou zoiets zijn als

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.

Je kunt dat dan in een SQL-statement aanroepen (ik zou denken dat je op zijn minst een derde kolom met de kolomnaam zou willen)

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.

Een efficiëntere benadering zou zijn om Tom Kyte's show_table gepijplijnde tabelfunctie aan te passen.




  1. Django Rest Framework-paginering extreem traag tellen

  2. Arabisch opslaan in SQL-database

  3. MariaDB JSON_LENGTH() uitgelegd

  4. Heroku Rails 4 kon geen verbinding maken met de server:verbinding geweigerd