MySQL查詢字段實現字符串分割split功能的示例代碼
問題背景
查詢MySQL中用逗號分隔的字段【a,b,c】是否包含【a】
場景模擬
現有表【ec_logicplace】,如下圖所示:
要求判斷數值【1】是否存在于表【ec_logicplace】中的【actual_place_id】中
方法實現
首先將【actual_place_id】字段用逗號拆分查詢出來
通用模板為:
SELECT SUBSTRING_INDEX( SUBSTRING_INDEX( 'a,b,c', ',', help_topic_id + 1 ), ',',- 1 ) AS num FROM mysql.help_topic WHERE help_topic_id < LENGTH( 'a,b,c' ) - LENGTH( REPLACE ( 'a,b,c', ',', '' ) ) + 1
上述所用的關鍵字包含【SUBSTRING_INDEX】,【LENGTH】,【REPLACE】。
SUBSTRING_INDEX
用于字符串拆分,格式為:
SUBSTRING_INDEX(str,delim,count)
參數 | 含義 |
str | 需要拆分的字符串 |
delim | 分隔符,通過某字符進行拆分 |
count | 當 count 為正數,取第 n 個分隔符之前的所有字符; 當 count 為負數,取倒數第 n 個分隔符之后的所有字符。 |
舉例:
獲取第二個以“,”逗號為分隔符之前的所有字符
SUBSTRING_INDEX('a,b,c',',',2)
獲取倒數第二個以“,”逗號為分隔符之前的所有字符
SUBSTRING_INDEX('a,b,c',',',-2)
LENGTH
獲取字符串的長度,格式為:
LENGTH(str)
參數 | 含義 |
str | 需要計算長度的字符串 |
舉例:
獲取’a,b,c‘字符串的長度
LENGTH('a,b,c')
REPLACE
替換函數,格式為:
replace(str,from_str,to_str)
參數 | 含義 |
str | 需要進行替換的字符串 |
from_str | 需要被替換的字符串 |
to_str | 需要替換的字符串 |
舉例:
將分隔符“,”逗號替換成“、”頓號
REPLACE('a,b,c',',','、')
SQL解析
此處用的是MySQL庫的help_topic 表的help_topic_id 來作為變量,因為help_topic_id 是自增的。
原理:把要拆分的字符串拆分,首先需要知道最后要被拆分成多少個字符串,也就是上述所說的count,其次是需要知道用什么來進行拆分。所以分為兩個步驟來進行sql編寫
step1:獲取最后需被拆分成多少個字符串,用help_topic_id 來模擬遍歷第n個字符串:
help_topic_id < LENGTH('a,b,c')-LENGTH(REPLACE('a,b,c',',',''))+1
step2:根據逗號進行拆分字符串,也就是SUBSTRING_INDEX函數,最后把結果賦值給num字段
SUBSTRING_INDEX(SUBSTRING_INDEX('a,b,c',',',help_topic_id+1),',',-1) AS num
需要注意的是,這里使用的是MySQL中的內置表help_topic,里面有508條數據(不同版本數據條數有差別),用戶需要有對該表查詢的權限,這樣的話只滿足分割數量少于508條的字符串,否則應該自定義輔助表,設置更大的一個遞增列
當需要分割的字符串是查詢出來的時候
當需要分割的字符串是查詢出來的時候,可能不止一條數據,直接嵌入模板SQL會報錯
這時候可以使用存儲過程來進行處理,也就是本次遇到的問題
要求判斷數值【1】是否存在于表【ec_logicplace】中的【actual_place_id】中
首先創(chuàng)建一個存儲過程,一個輸入參數一個輸出參數,輸入參數為需要判斷的值,輸出參數為判斷結果,我們以0,1來進行判斷,0是輸入參數不存在于表字段中,1是輸入參數存在于表字段中。存儲過程如下
CREATE DEFINER=`root`@`%` PROCEDURE `queryActualInLogic`(IN `actualPlaceId` bigint,OUT `isContain` int) BEGIN DECLARE v_column VARCHAR(100); -- 設置終止標記 declare done int default 0; # 查詢出所有待判斷的字段值集合 declare table_loop cursor for SELECT actual_place_id FROM ec_logicplace WHERE actual_place_id IS NOT NULL; # 捕獲系統(tǒng)拋出的 not found 錯誤,如果捕獲到,將 done 設置為 1 相當于try異常 declare continue handler for not found set done=1; open table_loop; out_loop:LOOP # 遍歷字段值,一一賦值 FETCH NEXT FROM table_loop into v_column; IF done = 1 THEN LEAVE out_loop; END IF; # 遍歷字段值,拆分后進行判斷,存在則賦值1,不存在則賦值0 SET @STMT = CONCAT("SELECT COALESCE(count(1),0) AS isContain into @v_count FROM (SELECT SUBSTRING_INDEX( SUBSTRING_INDEX( '",v_column,"' , ',', help_topic_id + 1 ), ',', -1 ) AS num FROM mysql.help_topic WHERE help_topic_id < LENGTH( '",v_column,"' ) - LENGTH ( REPLACE ( '",v_column,"' , ',', '' ) ) + 1 ) t WHERE t.num = ",actualPlaceId,";"); PREPARE STMT FROM @STMT; #執(zhí)行語句 EXECUTE STMT; deallocate prepare STMT; set isContain = @v_count; if isContain = 1 THEN LEAVE out_loop; END IF; END LOOP out_loop; close table_loop; END
測試:
后續(xù)MyBatis調用存儲過程的返回值進行業(yè)務判斷見
到此這篇關于MySQL查詢字段實現字符串分割split功能的示例代碼的文章就介紹到這了,更多相關MySQL字符串分割內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring boot整合Mybatis實現級聯一對多CRUD操作的完整步驟
這篇文章主要給大家介紹了關于Spring boot整合Mybatis實現級聯一對多CRUD操作的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧2019-07-07SpringBoot 自動掃描第三方包及spring.factories失效的問題解決
這篇文章主要介紹了SpringBoot 自動掃描第三方包及spring.factories失效的問題,本文給大家分享最新解決方法,需要的朋友可以參考下2023-05-05解決Spring Boot 多模塊注入訪問不到jar包中的Bean問題
這篇文章主要介紹了解決Spring Boot 多模塊注入訪問不到jar包中的Bean問題。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09排查Failed?to?validate?connection?com.mysql.cj.jdbc.Connec
這篇文章主要介紹了Failed?to?validate?connection?com.mysql.cj.jdbc.ConnectionImpl問題排查,具有很好的參考價值,希望對大家有所幫助2023-02-02