一、当字符串之间没有分隔符
遍历字符串时我们需要一个辅助表与原表做连接查询
辅助表中的数字就是表示字符串中各个字符的位置
要求该辅助表必须有足够多的行数保证循环操作的次数
例:把emp表中等于king的字符串拆开来显示为4行,每行一个字符
辅助表T10
SELECT SUBSTR(list.val,iter.pos,1) c FROM( (SELECT ename val FROM emp WHERE ename = 'king') list INNER JOIN (SELECT id pos FROM t10) iter ON iter.pos <= LENGTH(list.val) );
结果:
分析:
首先做两表内连接,连接的条件是辅助表的数字pos要小于等于字符串中字符的总个数
其实,在这里,辅助表中连续的数字就对应了字符串中每个字符的位置
如果先不截取字符串,而是先把两表连接的结果都查询出来,结果如下图
发现:一个字符串有多少个字符,就会出现多少行,并且每一行都有连续对应的数字pos
我们再根据每一行的数字去截取相对应字符串位置的字符
二、当字符串之间有分隔符
此时我们人需要辅助表做连接查询,但是连接查询的条件发生了变化;
此外需要substring_index () 函数来截取字符串。
例如:t1表中有一句话是“今天周末,我看了CBA篮球总决赛,最终广东队赢得了冠军”,把这句话以逗号为分隔符拆开,显示成3行
1 SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(list.val,',',iter.pos),',',-1) c 2 FROM( 3 (SELECT '今天周末,我看了CBA篮球总决赛,最终广东队赢得了冠军' val FROM t1) LIST 4 INNER JOIN 5 (SELECT id pos FROM t10) iter 6 ON iter.pos <= ((LENGTH(list.val)-LENGTH(REPLACE(list.val,',','')))/3+1) #此处除以三是因为汉字占3个字节 7 );
结果:
分析:
此时,辅助表中数字的作用不再是表示字符串中字符的位置了,而是用来标记分隔符出现的个数
(LENGTH(list.val)-LENGTH(REPLACE(list.val,',','')))/3的最终结果是2,表示这句话一共有2个逗号;
在此基础上加一是因为2个逗号把这句话分成了3段,所以 iter.pos最终有三个数字
根据substring_index函数的用法可知,
SUBSTRING_INDEX(list.val,',',iter.pos)是用来找出处第一个一直到第三个逗号前的字符串
在上图结果下,使用 SUBSTRING_INDEX(SUBSTRING_INDEX(list.val,',',iter.pos),',',-1)
找出从右边开始数,分隔符第一次出现后右边全部的字符串,及最终结果