一、當字符串之間沒有分隔符
遍歷字符串時我們需要一個輔助表與原表做連接查詢
輔助表中的數字就是表示字符串中各個字符的位置
要求該輔助表必須有足夠多的行數保證循環操作的次數
例:把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)
找出從右邊開始數,分隔符第一次出現后右邊全部的字符串,及最終結果