oracle unpivot 多列到多列

Posted

技术标签:

【中文标题】oracle unpivot 多列到多列【英文标题】:oracle unpivot multiple columns into multiple columns 【发布时间】:2020-07-08 05:38:07 【问题描述】:

我有一个有 10 列的表。我想使用 unpivot 将其转换为 2 列。下面是我的表格。我尝试使用子句(从 all_tab_columns 获取聚合列),unpivot 但给出错误简单列错误或子句错误。有人建议我在哪里出错。

input table
KEY_COL COL_A COL_B COL_C..till COL_J
1        a,b,c,d,e,f,g,h,i,j
2        x,y,a,s,f,g,e,r,g,d

output table
KEY_COL COLM VALUE
1   COL_A    a
1   COL_B    b
.
.
.
1  COL_J     j
2  COL_A     x
2  COL_B     y
.
.
.
2  COL_J    d

知道怎么做吗?

【问题讨论】:

是的,你已经提到了我最近意识到的 ..._tab_columns 视图。 【参考方案1】:

您可以按如下方式使用UNPIVOT 子句:

SQL> --sample data
SQL> with your_Table(id,cola,colb)
  2  as (select 1,'a','b' from dual union all
  3  select 2,'c','d' from dual)
  4  -- your query starts from here
  5  select * from your_Table
  6  unpivot (dataa for col in (cola,colb)); -- you need to pass 10 columns here

        ID COL  D
---------- ---- -
         1 COLA a
         1 COLB b
         2 COLA c
         2 COLB d

SQL>

我只使用了 2 列,您需要将其扩展为使用 10 列

或者其他方法,你可以使用UNION ALL 10 次,不过会很长。

SQL> --sample data
SQL> with your_Table(id,cola,colb)
  2  as (select 1,'a','b' from dual union all
  3  select 2,'c','d' from dual)
  4  -- your query starts from here
  5  select ID, 'COLA' AS COL, COLA from your_Table
  6  UNION ALL
  7  select ID, 'COLB' AS COL, COLB from your_Table
  8  ORDER BY ID, COL;

        ID COL  C
---------- ---- -
         1 COLA a
         1 COLB b
         2 COLA c
         2 COLB d

SQL>

【讨论】:

谢谢你。我正在制定一般解决方案。动态列。我必须转换很多表。我正在考虑 listagg 函数 for_in 子句。不是硬编码。 所以我已经给出了答案 - i have a table with 10 columns. i want to convert this to 2 columns using unpivot. Oracle 不允许在 IN 子句中使用动态列列表。你应该使用动态查询然后 您是否有一个包含十列或一列包含以逗号分隔的值的表?如果第一个是您在问题中所述的选择,那么 listagg() 函数没有意义 @SrinathP ,并且 Tejash 所说的对于标准 SQL 案例来说是完全正确的。也许您可以通过字典视图(例如user_tab_columns)查找动态 SQL。 @BarbarosÖzhan - 我举了一个有十列的表的例子。我有更多具有不同列数的表。所以思考动态解决方案。是的,我正在使用 user_tab_columns。我已经提到过这个问题。【参考方案2】:

为了获得 Unpivoting 的动态结果,然后使用这样的 PL/SQL 块

SQL> SET SERVEROUTPUT ON

SQL> DECLARE
  val  VARCHAR2(4000);
  tbl  VARCHAR2(40)  := 'TAB';
BEGIN
  DBMS_OUTPUT.PUT_LINE('KEY_COL    COLM      VALUE ');  
  DBMS_OUTPUT.PUT_LINE('-------    -----     ------'); 
  FOR c IN (  
              SELECT t.*, c.* 
                FROM user_tab_columns c
               CROSS JOIN tab t
               WHERE table_name = tbl AND column_id > 1
               ORDER BY t.key_col, c.COLUMN_ID  
           )
  LOOP 
      EXECUTE IMMEDIATE 'SELECT '||c.column_name||' FROM '||tbl||' WHERE key_col = :kc' 
                   INTO val 
                  USING c.key_col;  

      DBMS_OUTPUT.PUT_LINE(c.key_col||'          '||c.column_name||'     '||val);        
  END LOOP;
END;   
/

可能有助于从字典视图user_tab_columns 中提取每个列的值,前提是该表在您的架构中。否则,该视图应通过指定所有者替换为all_tab_columns

游标的查询循环获取样本表中除键列之外的所有值。

Demo

【讨论】:

以上是关于oracle unpivot 多列到多列的主要内容,如果未能解决你的问题,请参考以下文章

UnPivot 多列 MSSQLServer

PIVOT/UNPIVOT 多行多列

多列,多表列到行 unpivot

SQL unpivot 多列

如何对具有常量/缺失列的多列使用 unpivot?

SQL Unpivot 多列数据