MySQL数据转换:如何高效地实现行列互转和字符串拆分?

记得有一次,在一个项目中,我需要将用户表中以逗号分隔的字符串字段“Hobbies”拆分成单独的行,以方便后续的数据分析和处理。
该字段存储用户可能有的各种兴趣爱好,例如“篮球、足球、编程”。

当时我的MySQL版本是5 .7 ,所以无法继续使用JSON_TABLE等高级功能。
我记得存储过程。
虽然写起来有点困难,但我终于还是写完了。
我创建了一个存储过程,并使用 SUBSTRING_INDEX 函数逐一提取每个感兴趣的元素,然后将它们插入到新表中。

过程是这样的:首先,我定义一个临时表来存储拆分数据,然后循环遍历原始表中的每个用户,使用 SUBSTRING_INDEX 提取每个兴趣的值并将其插入到临时表中。
最后,我将临时表中的数据插入到感兴趣的最终表中。

这个过程大约需要一个下午的时间。
虽然有点慢,但最终的效果还是不错的。
用户表中的数据被平滑地划分为单独的行,后续的数据处理变得更加容易。

等一下,我突然想到,如果我当时使用的MySQL版本是8 .0以上的话,那么事情可能会容易一些,直接用JSON_TABLE就可以了。
不过,这也让我认识到掌握不同MySQL版本的特性对于解决实际问题是多么重要。

MySQL的一行转换为多行技巧mysql一行变成多行

坦白讲,MySQL 中将一行转换为多行只有两种方法:UNION ALL 和 GROUP BY,但正确的时机很重要。

先用UNION ALL比较简单粗暴。
比如我们去年做的电商项目中,有一个用户表。
有一个兴趣列,存储用逗号分隔的爱好。
我们想把它分成一行。
关键点:首先使用一个数值表(从0到9 的子查询)配合SUBSTRING_INDEX进行一一分段。
例如,SUBSTRING_INDEX('篮球、足球、编程',',',1 ) 将得到“篮球”。
请注意 REPLACE 处理空格。
去年我忘记了这一步,结果出现了很多空行。
还有一点是,在分割之前要确认最大长度。
我们的项目爱好最多有5 个,所以数表应该只有5 个。
很多人不注意这一点,如果你努力跑9 次就会报错。

后来发现GROUP BY更灵活。
例如,有一个 Orders 表,Items 列存储以分号分隔的产品 ID。
我们需要拆分一行并将其插入到新表中。
关键场景是带条件过滤,比如只去掉“Apple”以上的产品。
先拆分(总是使用数字表和SUBSTRING_INDEX),然后使用GROUP BY order_id进行分组,但是注意这里不能直接GROUP BY order_id,需要添加过滤条件元素!= 'Apple',否则整行都会被拆分。
去年有一个要求,但是我忘记加上了,整个桌子都拆了。
还有另一个关键细节。
拆解后需要排序,否则数据会随机。
您可以使用 ORDER BY 数字来执行此操作。

一开始我也以为GROUP BY更通用,后来发现UNION ALL在分割定长字符串时速度更快。
等等,还有一件事,如果分割列有NULL值,这两种方法都必须处理,否则整行都会丢失。

建议先用UNION ALL训练,数据量大时再考虑GROUP BY优化。
您认为 UNION ALL 最适合哪种场景?