想用一个存储过程实现一个纵表转横表的功能,情况如下,有两张表:
表A:tmp_user_1 (USER_ID number,CREATE_date date);
表B:tmp_user_2 (USER_ID NUMBER,MODE_NAME VARCHAR2(100),TYPE_ID NUBER) ;
表A中一个user_id一条记录,数据没有重复,全量的用户;
表B中一个user_id存在多条记录,但是对于同一个MODE_NAME下user_id只有一条记录。也就是说B表一个用户可能存在多个mode_name.但是MODE_NAME的数量是不定的,根据时间的推移,COUNT(DISTINCT MODE_NAME)的值是不一样的。我现在想做的就是想用一个存储过程实现将B表拉成横表,即表B变成表C:tmp_user_3(user_id,mode_name_1,mode_name_2,...).大概知道用游标,然后拼接SQL来实现,但是很少写存储过程,写不出来,在这里请高人帮忙。存储过程横表

解决方案 »

  1.   

    星期五了,心情不错,给你来个详细的----------------新建测试表
    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;
      

  2.   

    http://blog.csdn.net/jxzkin/article/details/7949629
      

  3.   


    呵呵,你在itpub上也回答我了,测试了下,能用,谢谢!