【问题标题】:Oracle pivoting unknown number of column before execution timeOracle 在执行时间之前旋转未知数量的列
【发布时间】:2015-05-15 22:09:57
【问题描述】:

我有这样的事情:

id  cod
1   a
1   b
1   c
2   d
2   e
3   f
3   g

我需要这样的东西:

id  cod 1   cod 2   cod 3
1   a       b       c
2   d       e   
3   f       g   

您知道在执行时间之前无法知道 oracle 必须生成多少列。

【问题讨论】:

  • 为什么id=1,鳕鱼a,属于cod1而不是cod2cod3,您需要指定该逻辑。我的意思是您使用哪种逻辑将 cod 行列为列?得到这样的结果是可能的,但你需要澄清这个问题。
  • 您可以对 XML 进行透视,也可以在 pl/sql 中使用动态 SQL 首先查询源表以获取结果中所需的列数,然后形成查询并立即执行。跨度>
  • 我需要知道每个 id 关联的 cod 是什么

标签: oracle oracle11g pivot


【解决方案1】:

您好,您也可以使用此查询。

--创建测试数据

create table test_me(id_num  number,val varchar2(10));

insert all 

into test_me 

values(1,'a')

into test_me values (1,'b')

into test_me values (1,'c')

into test_me values (2,'d')

into test_me values (2,'e')

into test_me values (3,'f')

into test_me values (3,'g')

select 1 from dual;

select * from 

(

select id_num,val,row_number() over (partition by  id_num order by val) rn

from test_me )

pivot (max(val) for id_num in(1 as val_1,2 as val_2,3 as val_3));

SQLFiddle 演示在这里 http://sqlfiddle.com/#!4/4206f/1

【讨论】:

    【解决方案2】:

    您可以使用过程 p_pivot,代码如下。它根据您的表动态构建视图 v_test。 然后你可以像这里一样从这个视图中选择:

    Connected to Oracle Database 10g Release 10.2.0.4.0 
    
    SQL> execute p_pivot;
    
    PL/SQL procedure successfully completed
    
    SQL> select * from v_test;
    
            ID COD1  COD2  COD3
    ---------- ----- ----- -----
             1 a     b     c
             2 d     e     
             3 f     g     
    

    过程(请在代码中将表名从test更改为您的表名):

    create or replace procedure p_pivot is
      v_cols number;
      v_sql varchar2(4000);
    begin
      select max(cnt) into v_cols
        from (select count(1) cnt from test group by id);
    
      v_sql := 
      'create or replace view v_test as 
      with t as (select row_number() over (partition by id order by cod) rn, test.* from test)
      select id';
    
      for i in 1..v_cols
      loop
        v_sql := v_sql || ', max(decode(rn, '||i||', cod)) cod'||i;
      end loop;
      v_sql := v_sql || ' from t group by id';
      execute immediate v_sql;
    end p_pivot;
    

    【讨论】:

      【解决方案3】:

      没有办法做到这一点。 Oracle 在编译查询时必须知道列数。

      假设您使用这样的查询创建了一个视图。每次查看视图时,视图的列数都会不同。

      此外,应该没有办法从这样的查询中获取数据。因为在评估表中的所有数据之前,您不知道有多少列。

      【讨论】:

      • 让我们想象一下,我希望始终生成 50 列(它们就足够了):我该怎么做?
      猜你喜欢
      • 1970-01-01
      • 2012-06-08
      • 1970-01-01
      • 2011-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-21
      • 1970-01-01
      相关资源
      最近更新 更多