MySQL 5.7.16 字符串拆分 -> 单列变多行记录(转发)

时间:2024-01-03 08:53:02

http://blog.csdn.net/mchdba/article/details/53889803

-------------------------------------------------------------------------------

  1. mysql> create table t1(c1 varchar(32),c2 varchar(32));
  2. Query OK, 0 rows affected (0.02 sec)
  3. mysql> INSERT INTO t1 SELECT 'man' c1,'123,234,567,789' c2 UNION ALL SELECT 'guo','-12,-87,-09,132' UNION ALL SELECT 'fang','1024,2387,1209,1032';
  4. Query OK, 3 rows affected (0.02 sec)
  5. Records: 3  Duplicates: 0  Warnings: 0
  6. mysql> select * from t1;
  7. +------+---------------------+
  8. | c1   | c2                  |
  9. +------+---------------------+
  10. | man  | 123,234,567,789     |
  11. | guo  | -12,-87,-09,132     |
  12. | fang | 1024,2387,1209,1032 |
  13. +------+---------------------+
  14. 3 rows in set (0.00 sec)
  15. mysql>

需要达到的效果是,左边变成右边,按照逗号拆分出来,单列变成多行记录,而且保留原来的其它列数据,如下图所示:

MySQL 5.7.16 字符串拆分 -> 单列变多行记录(转发)

#,blog原地址:http://blog.csdn.net/mchdba/article/details/53889803,作者mchdba,谢绝转载

这个复杂的实现,单条的sql或者几条sql无法达到,需要临时表存储中间数据,所以编写存储过程,间接实现,存储过程如下:

  1. DELIMITER $$
  2. USE `test`$$
  3. DROP PROCEDURE IF EXISTS `proc_cur_split_str`$$
  4. USE `test`$$
  5. CREATE PROCEDURE test.proc_cur_split_str()
  6. BEGIN
  7. DECLARE v_c1 VARCHAR(20);
  8. DECLARE v_c2 VARCHAR(60);
  9. DECLARE _done INT DEFAULT 0;
  10. DECLARE cur_strs CURSOR FOR SELECT c1,c2 from test.t1 ;
  11. DECLARE CONTINUE HANDLER FOR NOT FOUND BEGIN SET _done=1; END;
  12. DROP TABLE IF EXISTS test.ZZ_2;
  13. CREATE TABLE test.ZZ_2(C1 VARCHAR(20),CN VARCHAR(60));
  14. OPEN cur_strs;
  15. FETCH cur_strs INTO v_c1, v_c2;
  16. WHILE _done != 1  DO
  17. DROP TABLE IF EXISTS test.ZZ_1;
  18. CREATE TABLE ZZ_1(CN VARCHAR(60));
  19. SET @b=v_c2;
  20. SET @a = CONCAT(CONCAT("insert into test.ZZ_1 values('",REPLACE(@b,',',"'),('")),"')");
  21. -- SELECT @a;
  22. PREPARE stmt1 FROM @a;
  23. EXECUTE stmt1;
  24. -- SELECT v_c1,t.* FROM test.ZZ_1 t;
  25. INSERT INTO ZZ_2 SELECT v_c1,t.* FROM test.ZZ_1 t;
  26. COMMIT;
  27. -- SELECT * FROM test.ZZ_2;
  28. FETCH cur_strs INTO v_c1, v_c2;
  29. END WHILE;
  30. CLOSE cur_strs;
  31. SELECT * FROM test.ZZ_2;
  32. END;

执行存储过程,得到执行结果,符合心理预期,单列C1变成多行,并且保留了原来的其它字段c1的数据值,如下所示,

MySQL 5.7.16 字符串拆分 -> 单列变多行记录(转发)