想用一个存储过程实现一个纵表转横表的功能,情况如下,有两张表:
表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来实现,但是很少写存储过程,写不出来,在这里请高人帮忙。存储过程横表
表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来实现,但是很少写存储过程,写不出来,在这里请高人帮忙。存储过程横表
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;
呵呵,你在itpub上也回答我了,测试了下,能用,谢谢!