MySQL 字段根据逗号分割实现列转行

发布时间 2023-09-13 14:11:11作者: 唏嘘-

表数据:

 期望数据:

实现sql:

select 
a.id,
b.help_topic_id +1,
a.execute_name,
#substring_index(a.execute_name,',',b.help_topic_id+1),
substring_index(substring_index(a.execute_name,',',b.help_topic_id+1),',',-1) 
from `user` a
left join mysql.help_topic b
on b.help_topic_id < (length(a.execute_name) - length(replace(a.execute_name,',',''))+1)
order by a.id, b.help_topic_id

使用到的函数:

1、SUBSTRING_INDEX(str,delim,count):

str:要处理的字符串
delim:分隔符
count:计数
正数:从左往右数,第N个分隔符的左边的全部内容,
负数,那么就是从右边开始数,第N个分隔符右边的所有内容

2、help_topic这张表是mysql自带的连续数列的表

mysql.help_topic这张表我们只用到了它的help_topic_id,
可以看到这个help_topic_id是从0开始一直连续的,
join这张表只是为了确定数据行数。
现在假设我的mysql.help_topic一共只有5条数据,那么最多可转成5行数据,若果现在字段的名字有6个就不能用mysql.help_topic这张表了。

3、substring_index(substring_index(a.execute_name,',',b.help_topic_id+1),',',-1)

select 
a.id,
b.help_topic_id +1,
a.execute_name,
#从左往右循环取 b.help_topic_id+1 个字符
substring_index(a.execute_name,',',b.help_topic_id+1), 
#从右往左第一个,右边的数据
substring_index(substring_index(a.execute_name,',',b.help_topic_id+1),',',-1) 
from `user` a
left join mysql.help_topic b
on b.help_topic_id < (length(a.execute_name) - length(replace(a.execute_name,',',''))+1)
order by a.id, b.help_topic_id

4、on条件后面的b.help_topic_id < (length(a.execute_name) - length(replace(a.execute_name,',',''))+1)

得到被逗号分隔的字段一共有几个(既计算出原始的字段长度,和去掉逗号的字段长度,两者的差就是有几个逗号,三个逗号就表示有四个字段...)

5、join 这个join最基本原理是笛卡尔积。通过这个方式来实现循环

这种方法的缺点在于,我们需要一个拥有连续数列的独立表(这里是incre_table)。并且连续数列的最大值一定要大于符合分割的值的个数。
例如有一行的mSize 有100个逗号分割的值,那么我们的incre_table 就需要有至少100个连续行。
mysql内部也有现成的连续数列表可用。如mysql.help_topic:一般能满足于大部分需求了。

参考:https://www.cnblogs.com/xcyjblog/p/15134312.html