MySql字符串拆分實(shí)現(xiàn)split功能(字段分割轉(zhuǎn)列)
需求描述
數(shù)據(jù)庫中 num字段值為:
實(shí)現(xiàn)的效果:需要將一行數(shù)據(jù)變成多行
實(shí)現(xiàn)的sql
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num FROM mysql.help_topic WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
案例演示
CREATE TABLE `company` ( `id` int(20) DEFAULT NULL, `name` varchar(100) DEFAULT NULL, `shareholder` varchar(100) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8; INSERT INTO `company` VALUES ('1', '阿里巴巴', '馬云'); INSERT INTO `company` VALUES ('2', '淘寶', '馬云,孫正義');
1、原始數(shù)據(jù)演示
2、處理結(jié)果演示
3、sql語句
SELECT a.id , a.NAME , substring_index(substring_index(a.shareholder, ',', b.help_topic_id + 1), ',', - 1) AS shareholder FROM company a INNER JOIN mysql.help_topic b ON b.help_topic_id < (length(a.shareholder) - length(REPLACE(a.shareholder, ',', '')) + 1)
涉及的知識(shí)點(diǎn)如下:
字符串拆分: SUBSTRING_INDEX(str, delim, count)
參數(shù)解說 解釋
str 需要拆分的字符串
delim 分隔符,通過某字符進(jìn)行拆分
count 當(dāng) count 為正數(shù),取第 n 個(gè)分隔符之前的所有字符; 當(dāng) count 為負(fù)數(shù),取倒數(shù)第 n 個(gè)分隔符之后的所有字符。
舉例
(1)獲取第2個(gè)以逗號(hào)為分隔符之前的所有字符。
SELECT SUBSTRING_INDEX('7654,7698,7782,7788',',',2);
(2)獲取最后一個(gè)到倒數(shù)第2個(gè)以逗號(hào)分隔符之后的所有字符
SELECT SUBSTRING_INDEX('7654,7698,7782,7788',',',-2);
所以,我們的核心代碼中的 -1 ,就是獲取以逗號(hào)為分隔符的最后一個(gè)值;也就是7788
替換函數(shù):replace( str, from_str, to_str)
參數(shù)名 解釋
str 需要進(jìn)行替換的字符串
from_str 需要被替換的字符串
to_str 需要替換的字符串
舉例
將分隔符逗號(hào)替換為空。
SELECT REPLACE('7654,7698,7782,7788',',','');
獲取字符串長(zhǎng)度:LENGTH( str )
參數(shù)名 解釋
str 需要計(jì)算長(zhǎng)度的字符串
獲取 ‘7654,7698,7782,7788’ 字符串的長(zhǎng)度
SELECT LENGTH('7654,7698,7782,7788')
實(shí)現(xiàn)的原理解析
【4.1】 實(shí)現(xiàn)sql
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num FROM mysql.help_topic WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
此處利用 mysql 庫的 help_topic 表的 help_topic_id 來作為變量,因?yàn)?help_topic_id 是自增的,當(dāng)然也可以用其他表的自增字段輔助。
help_topic 表:
注意,這個(gè)輔助表的ID最大長(zhǎng)度只有658;如果過長(zhǎng)的字符串,可能需要借助其他自增的輔助表(可以是現(xiàn)有表,也可以自己造一個(gè) 1,2,3,4 遞增的行即可)
【4.2】正式的原理解析
原SQL
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num FROM mysql.help_topic WHERE help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
Step1:首先獲取最后需被拆分成多少個(gè)字符串,利用 help_topic_id 來模擬遍歷 第n個(gè)字符串。
這一步核心就是獲取,有多少個(gè)分隔符,比如本文的案例,就是知道有多少個(gè)逗號(hào)
涉及的代碼片段:
help_topic_id < LENGTH('7654,7698,7782,7788')-LENGTH(REPLACE('7654,7698,7782,7788',',',''))+1
因?yàn)?help_topic_id是從0開始的,所以會(huì)得出 help_topic_id 值為:0~3,共4行數(shù)據(jù);
Step2:根據(jù)“,”逗號(hào)來拆分字符串,此處利用 SUBSTRING_INDEX(str, delim, count) 函數(shù),最后把結(jié)果賦值給 num 字段。
涉及的代碼片段:
SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) AS num
第一步:
以”,”逗號(hào)為分隔符,根據(jù) help_topic_id 的值來截取第n+1個(gè)分隔符之前所有的字符串。 (此處 n+1 是因?yàn)閔elp_topic_id 是從0開始算起,而此處需從第1個(gè)分隔符開始獲取。)
SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1) eg: 當(dāng) help_topic_id = 0時(shí),獲取到的字符串 = 7654 當(dāng) help_topic_id = 1時(shí),獲取到的字符串 = 7654,7698 …(以此類推)
第二步:
以”,”逗號(hào)為分隔符,截取倒數(shù)第1個(gè)分隔符之后的所有字符串。
SUBSTRING_INDEX(SUBSTRING_INDEX('7654,7698,7782,7788',',',help_topic_id+1),',',-1) eg: 根據(jù)第一步,當(dāng) help_topic_id = 0時(shí),獲取到的字符串 = 7654,此時(shí)第二步截取的字符串 = 7654 根據(jù)第一步,當(dāng) help_topic_id = 1時(shí),獲取到的字符串 = 7654,7698,此時(shí)第二步截取的字符串 = 7698 …(以此類推)
最終成功實(shí)現(xiàn)了以下效果 ~
擴(kuò)展:判斷外部值是否在 num列值中
【5.1】find_in_set
如果匹配到了會(huì)得出1;如下圖
實(shí)際業(yè)務(wù)中,我們只需要 where find_in_set(id,ids)>0
就可以判斷出;id列,是否在 ids列中出現(xiàn)過;做表連接的時(shí)候,也可以這樣;
【5.2】instr
我們可以看出,instr是找出 參數(shù)2=》也就是上圖中的 ‘123’ 在參數(shù)1=》也就是上圖中的 ‘321,123,555,12345’ 中最開始出現(xiàn)的位置;
所以我們也只需要 where find_in_set(ids,id)>0 ,就可以判斷出 id 在 ids中出現(xiàn)過;
但這有一個(gè)問題,如果逗號(hào)分隔開的字符串,包含我們查找的字符串,也會(huì)顯示出來,這就不符合我們 根據(jù)分隔符 , 判斷 查找字符串id 是否出現(xiàn)在 ids 中;
如下:
我們本來想查以逗號(hào)為分隔的完全匹配,但是12345包含了 123 所以查出來的結(jié)果也是>0的,這不對(duì);
所以我們?yōu)榱吮苊膺@種情況,可以加上分隔符;然后再用 字符串+分隔符作為 查找的字符串 來 匹配;
我們被查找的字符串 ids 中 再加上一個(gè)正常的 123, 再查看,如下圖:確實(shí)是對(duì)的
文章參考
https://blog.csdn.net/pjymyself/article/details/81668157
https://www.cnblogs.com/gered/p/10797012.html#_label1
到此這篇關(guān)于MySql字符串拆分實(shí)現(xiàn)split功能(字段分割轉(zhuǎn)列)的文章就介紹到這了,更多相關(guān)MySql字符串拆分內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
給mysql數(shù)據(jù)庫的字段設(shè)默認(rèn)值方式
這篇文章主要介紹了給mysql數(shù)據(jù)庫的字段設(shè)默認(rèn)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10MySQL如何導(dǎo)入SQL數(shù)據(jù)庫的實(shí)戰(zhàn)舉例
在使用mysql數(shù)據(jù)庫是,經(jīng)常需要備份或者恢復(fù)數(shù)據(jù)庫數(shù)據(jù),最便捷的方式就是通過導(dǎo)出sql文件備份和直接執(zhí)行sql文件恢復(fù),下面這篇文章主要給大家介紹了關(guān)于MySQL如何導(dǎo)入SQL數(shù)據(jù)庫的相關(guān)資料,需要的朋友可以參考下2023-05-05MYSQL同步 Slave_IO_Running: No 或者Slave_SQL_Running: No的解決方法[已測(cè)
為了服務(wù)器更好的安全特將mysql服務(wù)器同步一下,show slave status\G出現(xiàn)了Slave_IO_Running: No 錯(cuò)誤,特整理了下,方便以后配置2011-06-06Mysql 自定義隨機(jī)字符串的實(shí)現(xiàn)方法
前段時(shí)間接了一個(gè)項(xiàng)目,需要用到隨機(jī)字符串,但是mysql的庫函數(shù)沒有直接提供,需要我們自己實(shí)現(xiàn)此功能,下面小編給大家介紹下Mysql 自定義隨機(jī)字符串的實(shí)現(xiàn)方法,需要的朋友參考下吧2016-08-08詳談innodb的鎖(record,gap,Next-Key lock)
下面小編就為大家?guī)硪黄斦刬nnodb的鎖(record,gap,Next-Key lock)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-03-03MySQL中你可能忽略的COLLATION實(shí)例詳解
mysql的collation大致的意思就是字符序,這篇文章主要給大家介紹了關(guān)于MySQL中COLLATION的相關(guān)資料,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05MySQL索引底層數(shù)據(jù)結(jié)構(gòu)詳情
這篇文章主要介紹了MySQL索引底層數(shù)據(jù)結(jié)構(gòu)詳情,下面文章圍繞MySQL索引底層數(shù)據(jù)結(jié)構(gòu)的相關(guān)資料展開全篇文章,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2021-12-12教你如何讓spark?sql寫mysql的時(shí)候支持update操作
spark提供了一個(gè)枚舉類,用來支撐對(duì)接數(shù)據(jù)源的操作模式,本文重點(diǎn)給大家介紹如何讓spark?sql寫mysql的時(shí)候支持update操作,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧2022-02-02MySQL生僻字插入失敗的處理方法(Incorrect string value)
最近,業(yè)務(wù)方反饋有個(gè)別用戶信息插入失敗,報(bào)錯(cuò)提示類似Incorrect string value:"\xF0\xA5 .....看這個(gè)提示應(yīng)該是字符集不支持某個(gè)生僻字造成的,需要的朋友可以參考下2017-05-05