oracle行转列,该如何处理

oracle行转列Cust prod1A1B1C2A2BReturnCustProd1Prod2Prod31ABC2ABNull怎么搞啊[解决办法]慢慢搞select C

oracle行转列
Cust prod
1       A
1       B
1       C
2       A
2       B

Return
Cust     Prod1     Prod2       Prod3
1           A            B               C
2           A            B               Null

怎么搞啊
[解决办法]
慢慢搞


select Cust,
MAX(decode(prod,'A','A')) Prod1, 
MAX(decode(prod,'B','B')) Prod2,
MAX(decode(prod,'C','C')) Prod3
from ax
GROUP BY Cust;

      CUST PROD1 PROD2 PROD3
---------- ----- ----- -----
         1 A     B     C
         2 A     B     

[解决办法]
要看数据是否固定了 如果不确定行数 只能用动态sql判断了 还要判断prod是否相同...
[解决办法]

--创建测试表 插入测试数据
create table tb1 (cust number,prod nvarchar2(5));
insert into tb1 values (1,'A');
insert into tb1 values (1,'B');
insert into tb1 values (1,'C');
insert into tb1 values (2,'A');
insert into tb1 values (2,'B');
commit;   

--创建存储过程
CREATE OR REPLACE PROCEDURE T_TEST
IS
  V_SQL NVARCHAR2(2000); 
  CURSOR CURSOR_1 IS
  SELECT DISTINCT PROD 
  FROM TB1
  ORDER BY PROD;
 
    BEGIN
      V_SQL := 'SELECT CUST ';
      FOR V_TB IN CURSOR_1
      LOOP
        V_SQL := V_SQL 
[解决办法]
 ',' 
[解决办法]
 'MAX(DECODE(T.PROD,'''
[解决办法]
 V_TB.PROD 
[解决办法]
 ''',T.PROD,NULL)) AS PROD_'
[解决办法]
 V_TB.PROD 
[解决办法]
'';
      END LOOP;
      V_SQL := V_SQL 
[解决办法]
 ' FROM  TB1 T' ;
      V_SQL := V_SQL 
[解决办法]
 ' GROUP BY CUST';
     DBMS_OUTPUT.PUT_LINE(V_SQL);
    --EXECUTE IMMEDIATE V_SQL;
    END;


--执行存储过程 返回sql 执行结果

     CUST   PROD_A  PROD_B  PROD_C
-------------------------------------------
11ABC
22AB

--继续插入测试数据
insert into tb1 values (2,'C');
insert into tb1 values (2,'D');
commit;  

--执行存储过程 返回查询语句

     CUST   PROD_A  PROD_B  PROD_C  PROD_D
-------------------------------------------
11ABC
22ABCD

--删除测试表和测试存储过程
--DROP TABLE TB1
--DROP PROCEDURE T_TEST

[解决办法]
7、动态行转不定列
----------------新建测试表
CREATE TABLE tmp_user_2(USER_ID NUMBER,MODE_NAME VARCHAR2(100),TYPE_ID NUmBER);

----------------第一部分测试数据
INSERT INTO tmp_user_2 VALUES(1001, 'M1',1); 
INSERT INTO tmp_user_2 VALUES(1001, 'M2',2);
INSERT INTO tmp_user_2 VALUES(1002, 'M1',3);
INSERT INTO tmp_user_2 VALUES(1002, 'M2',4);
INSERT INTO tmp_user_2 VALUES(1002, 'M3',5);
INSERT INTO tmp_user_2 VALUES(1003, 'M1',6);
COMMIT;

----------------行转列存储过程
CREATE OR REPLACE PROCEDURE P_tmp_user_2 IS
  V_SQL VARCHAR2(2000);


  CURSOR CURSOR_1 IS
    SELECT DISTINCT T.MODE_NAME FROM tmp_user_2 T ORDER BY MODE_NAME;

BEGIN
  V_SQL := 'SELECT USER_ID';
  FOR V_XCLCK IN CURSOR_1 LOOP
    V_SQL := V_SQL 
[解决办法]
 ',' 
[解决办法]
 'SUM(DECODE(MODE_NAME,''' 
[解决办法]
 V_XCLCK.MODE_NAME 
[解决办法]

             ''',TYPE_ID,0)) AS ' 
[解决办法]
 V_XCLCK.MODE_NAME;
  END LOOP;

  V_SQL := V_SQL 
[解决办法]
 ' FROM tmp_user_2 GROUP BY USER_ID';
  --DBMS_OUTPUT.PUT_LINE(V_SQL);
  V_SQL := 'CREATE OR REPLACE VIEW tmp_user_3  AS ' 
[解决办法]
 V_SQL;
  --DBMS_OUTPUT.PUT_LINE(V_SQL);
  EXECUTE IMMEDIATE V_SQL;
END;

----------------执行存储过程
BEGIN
  P_tmp_user_2;               
END;

----------------查看结果
SELECT * FROM tmp_user_3;

----------------第二部分测试数据
INSERT INTO tmp_user_2 VALUES(1003, 'M2',7); 
INSERT INTO tmp_user_2 VALUES(1004, 'M5',8); 
COMMIT;

----------------执行存储过程
BEGIN
  P_tmp_user_2;               
END;
----------------查看结果
SELECT * FROM tmp_user_3;




[解决办法]
http://wenku.baidu.com/view/d63a5d19ff00bed5b9f31de1.html

列或行不固定的 一般都是写一个游标,在里面遍历你的列或者行,拼装动态sql语句

楼上的都是讲动态sql 封装到一个试图中了,也可以直接返回一个结果集,直接使用。