簡體   English   中英

對不確定數量的列進行UNPIVOT

[英]UNPIVOT on an indeterminate number of columns

如何編寫一個查詢,將一個總共有1行和多列的表取消為具有2列的結果集:column_name和value。 我理解表的底層結構是真正的問題所在,但我無法改變它。 此查詢還必須不知道所述表中的列名稱和/或列數,因為列經常被添加(再次,我知道,糟糕的設計,不能改變它),我不想要每次添加新列時都必須更新查詢。 我已經能夠使用unpivot完成某些事情,但該查詢要求列名稱是硬編碼的。

這甚至可能嗎?

Oracle 11gR2

聽起來你想要將表格取消(旋轉將涉及從許多行和2列到具有許多列的1行)。 您很可能需要使用動態SQL生成查詢,然后使用DBMS_SQL包(或可能是EXECUTE IMMEDIATE )來執行它。 您還應該能夠構建一個執行unpivoting的管道化表函數。 您還需要在流水線表函數中使用動態SQL,但它可能會減少代碼。 不過,我希望使用UNPIVOT的純動態SQL語句更有效。

一種低效的方法,但相對容易遵循的方法,就像是

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.

然后,您可以在SQL語句中調用它(我認為您至少需要第三列具有列名稱)

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.

更有效的方法是調整Tom Kyte的show_table流水線表函數

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM