用存储过程 拆分字段

AIDBOPS 2012-04-20 08:58:42
原表数据:
C1 C2
--- --------------
1 aa,bbb,cccc,ddd
2 eee,fff,gggg,hhhh

转化成格式
C1 c2
--- ----------
1 aa
1 bbb
1 cccc
1 ddd
2 eee
2 fff
2 gggg
2 hhhh
数据量很大,写一个存储过程实现上述的转化,怎么写效率高一点
...全文
315 7 打赏 收藏 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
rucypli 2012-04-20
  • 打赏
  • 举报
回复
楼上的函数很好,就是这个函数
nicenight 2012-04-20
  • 打赏
  • 举报
回复
推测楼主想要这样一个函数。居家旅行常备无患。

mysql> DELIMITER $$
mysql> DROP PROCEDURE IF EXISTS `split`$$
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE PROCEDURE `split`(
-> str VARCHAR(9999),
-> sep CHAR(1)
-> )
-> BEGIN
-> DECLARE strlen INT;
-> DECLARE last_index INT;
-> DECLARE cur_index INT;
-> DECLARE cur_char VARCHAR(200);
-> DECLARE len INT;
-> SET cur_index=1;
-> SET last_index=0;
-> SET strlen=LENGTH(str);
-> DROP TABLE IF EXISTS tmp_tb_split;
-> CREATE TEMPORARY TABLE tmp_tb_split(
-> id INT AUTO_INCREMENT,
-> VALUE VARCHAR(20),
-> PRIMARY KEY (`ID`),
-> UNIQUE KEY `ID` (`ID`)
-> ) ;
-> WHILE(cur_index<=strlen) DO
-> BEGIN
-> IF SUBSTRING(str FROM cur_index FOR 1)=sep OR cur_index=strlen TH
EN
-> SET len=cur_index-last_index-1;
-> IF cur_index=strlen THEN
-> SET len=len+1;
-> END IF;
-> INSERT INTO tmp_tb_split(`value`)VALUES(SUBSTRING(str FROM (l
ast_index+1) FOR len));
-> SET last_index=cur_index;
-> END IF;
-> SET cur_index=cur_index+1;
-> END;
-> END WHILE;
->
-> SELECT * FROM tmp_tb_split;
-> END$$
Query OK, 0 rows affected (0.01 sec)

mysql> DELIMITER ;
mysql> CALL split('a,b,c',',');
+----+-------+
| id | VALUE |
+----+-------+
| 1 | a |
| 2 | b |
| 3 | c |
+----+-------+
3 rows in set (0.23 sec)

Query OK, 0 rows affected, 1 warning (0.23 sec)

mysql>
mysql>
mysql> DELIMITER $$
mysql>
mysql> DROP PROCEDURE IF EXISTS `split`$$
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> CREATE PROCEDURE `split`(
-> str VARCHAR(9999),
-> sep CHAR(1)
-> )
-> BEGIN
-> DECLARE strlen INT;
-> DECLARE last_index INT;
-> DECLARE cur_index INT;
-> DECLARE cur_char VARCHAR(200);
-> DECLARE len INT;
-> SET cur_index=1;
-> SET last_index=0;
-> SET strlen=LENGTH(str);
-> DROP TABLE IF EXISTS tmp_tb_split;
-> CREATE TEMPORARY TABLE tmp_tb_split(
-> id INT AUTO_INCREMENT,
-> VALUE VARCHAR(20),
-> PRIMARY KEY (`ID`),
-> UNIQUE KEY `ID` (`ID`)
-> ) ;
-> WHILE(cur_index<=strlen) DO
-> BEGIN
-> IF SUBSTRING(str FROM cur_index FOR 1)=sep OR cur_index=strlen TH
EN
-> SET len=cur_index-last_index-1;
-> IF cur_index=strlen THEN
-> SET len=len+1;
-> END IF;
-> INSERT INTO tmp_tb_split(`value`)VALUES(SUBSTRING(str FROM (l
ast_index+1) FOR len));
-> SET last_index=cur_index;
-> END IF;
-> SET cur_index=cur_index+1;
-> END;
-> END WHILE;
->
-> SELECT value FROM tmp_tb_split;
-> END$$
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;
mysql> CALL split('a,b,c',',');
+-------+
| value |
+-------+
| a |
| b |
| c |
+-------+
3 rows in set (0.38 sec)

Query OK, 0 rows affected (0.38 sec)



当然这个自定义函数效率可不保证,建议大量数据使用导出后另外处理,再导入。如果是 linux 系统,下面的脚本可以参考:

[nicenight@CSDN]# cat a.txt
1 aa,bbb,cccc,ddd
2 eee,fff,gggg,hhhh

[nicenight@CSDN]# awk '{split($2, ar, ","); for(s in ar) printf("%s\t%s\n", $1, ar[s]);}' a.txt
1 ddd
1 aa
1 bbb
1 cccc
2 hhhh
2 eee
2 fff
2 gggg
nicenight 2012-04-20
  • 打赏
  • 举报
回复
推测楼主想要这样一个函数。居家旅行常备无患。

mysql> DELIMITER $$
mysql> DROP PROCEDURE IF EXISTS `split`$$
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> CREATE PROCEDURE `split`(
-> str VARCHAR(9999),
-> sep CHAR(1)
-> )
-> BEGIN
-> DECLARE strlen INT;
-> DECLARE last_index INT;
-> DECLARE cur_index INT;
-> DECLARE cur_char VARCHAR(200);
-> DECLARE len INT;
-> SET cur_index=1;
-> SET last_index=0;
-> SET strlen=LENGTH(str);
-> DROP TABLE IF EXISTS tmp_tb_split;
-> CREATE TEMPORARY TABLE tmp_tb_split(
-> id INT AUTO_INCREMENT,
-> VALUE VARCHAR(20),
-> PRIMARY KEY (`ID`),
-> UNIQUE KEY `ID` (`ID`)
-> ) ;
-> WHILE(cur_index<=strlen) DO
-> BEGIN
-> IF SUBSTRING(str FROM cur_index FOR 1)=sep OR cur_index=strlen TH
EN
-> SET len=cur_index-last_index-1;
-> IF cur_index=strlen THEN
-> SET len=len+1;
-> END IF;
-> INSERT INTO tmp_tb_split(`value`)VALUES(SUBSTRING(str FROM (l
ast_index+1) FOR len));
-> SET last_index=cur_index;
-> END IF;
-> SET cur_index=cur_index+1;
-> END;
-> END WHILE;
->
-> SELECT * FROM tmp_tb_split;
-> END$$
Query OK, 0 rows affected (0.01 sec)

mysql> DELIMITER ;
mysql> CALL split('a,b,c',',');
+----+-------+
| id | VALUE |
+----+-------+
| 1 | a |
| 2 | b |
| 3 | c |
+----+-------+
3 rows in set (0.23 sec)

Query OK, 0 rows affected, 1 warning (0.23 sec)

mysql>
mysql>
mysql> DELIMITER $$
mysql>
mysql> DROP PROCEDURE IF EXISTS `split`$$
Query OK, 0 rows affected (0.00 sec)

mysql>
mysql> CREATE PROCEDURE `split`(
-> str VARCHAR(9999),
-> sep CHAR(1)
-> )
-> BEGIN
-> DECLARE strlen INT;
-> DECLARE last_index INT;
-> DECLARE cur_index INT;
-> DECLARE cur_char VARCHAR(200);
-> DECLARE len INT;
-> SET cur_index=1;
-> SET last_index=0;
-> SET strlen=LENGTH(str);
-> DROP TABLE IF EXISTS tmp_tb_split;
-> CREATE TEMPORARY TABLE tmp_tb_split(
-> id INT AUTO_INCREMENT,
-> VALUE VARCHAR(20),
-> PRIMARY KEY (`ID`),
-> UNIQUE KEY `ID` (`ID`)
-> ) ;
-> WHILE(cur_index<=strlen) DO
-> BEGIN
-> IF SUBSTRING(str FROM cur_index FOR 1)=sep OR cur_index=strlen TH
EN
-> SET len=cur_index-last_index-1;
-> IF cur_index=strlen THEN
-> SET len=len+1;
-> END IF;
-> INSERT INTO tmp_tb_split(`value`)VALUES(SUBSTRING(str FROM (l
ast_index+1) FOR len));
-> SET last_index=cur_index;
-> END IF;
-> SET cur_index=cur_index+1;
-> END;
-> END WHILE;
->
-> SELECT value FROM tmp_tb_split;
-> END$$
Query OK, 0 rows affected (0.00 sec)

mysql> DELIMITER ;
mysql> CALL split('a,b,c',',');
+-------+
| value |
+-------+
| a |
| b |
| c |
+-------+
3 rows in set (0.38 sec)

Query OK, 0 rows affected (0.38 sec)


当然这个自定义函数效率可不保证,建议大量数据使用导出后另外处理,再导入。如果是 linux 系统,下面的脚本可以参考:

[nicenight@CSDN]# cat a.txt
1 aa,bbb,cccc,ddd
2 eee,fff,gggg,hhhh

[nicenight@CSDN]# awk '{split($2, ar, ","); for(s in ar) printf("%s\t%s\n", $1, ar[s]);}' a.txt
1 ddd
1 aa
1 bbb
1 cccc
2 hhhh
2 eee
2 fff
2 gggg

yumenfeiyu945 2012-04-20
  • 打赏
  • 举报
回复
可以把原表的c2字段通过一些处理拼成一条批量插入的sql,再动态执行

select replace(concat('insert into t2 values(@id,\'',replace(c2,',','\'),(@id,\''),'\')'),'@id',c1) from t1;
AIDBOPS 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

直接用SQL语句+辅助表不行吗?
[/Quote]
能说具体些吗?刚学Mysql,还不是很清楚,谢谢
wwwwb 2012-04-20
  • 打赏
  • 举报
回复
直接用SQL语句+辅助表不行吗?
AIDBOPS 2012-04-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

可以把原表的c2字段通过一些处理拼成一条批量插入的sql,再动态执行
SQL code

select replace(concat('insert into t2 values(@id,\'',replace(c2,',','\'),(@id,\''),'\')'),'@id',c1) from t1;
[/Quote]

在存储过程中怎么动态执行 select 查询出来的insert语句呀?请教指点
内容概要:本文介绍了一个基于Python的无人机三维路径规划项目,采用差分进化算法(DE)在复杂三维环境中自动生成安全、高效的飞行路径。项目构建了包含起点、终点和多个长方体障碍物的三维空间模型,通过将路径编码为中间航点向量,利用差分进化进行全局优化。适应度函数综合考量路径长度、碰撞惩罚、安全距离、转弯代价、爬升能耗和高度约束,确保生成的路径在安全性、平滑性和可行性之间取得平衡。优化后还引入路径简化机制,删除冗余航点并检测直连安全性,以减少航点数量并提升可执行性。程序输出包括三维路径图、障碍物可视化、适应度收敛曲线及各项性能指标,支持后续扩展至真实地图、地形模型和动力学仿真。; 适合人群:具备Python编程基础,熟悉NumPy、matplotlib等库,从事无人机、智能优化、路径规划相关研究或开发的科研人员、研究生及工程师(工作年限1-3年或有相关项目经验者); 使用场景及目标:①解决城市、山区、工业区等复杂三维环境下的无人机避障路径规划问题;②学习差分进化算法在连续空间优化中的应用;③为低空物流、应急救援、巡检监测等实际场景提供算法原型与二次开发基础; 阅读建议:建议结合提供的完整代码与可视化结果进行实践,重点关注环境建模、适应度函数设计、差分进化实现与路径后处理逻辑,可通过调整参数(如种群规模、权重系数)观察优化效果变化,深入理解多目标权衡与算法调参策略。

57,062

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧