1. 程式人生 > 其它 >Mysql分割字串並對分割後的資料進行查詢翻譯

Mysql分割字串並對分割後的資料進行查詢翻譯

技術標籤:資料同步Mysqlmysqlelasticsearch

最近在處理ElasticSearch的資料同步。有一個需求要在sql裡對字串進行分割並對其進行翻譯。
需要同步的表裡的資料結構是這樣子的,而mysql的函式是沒有split的,只有SubString。這裡重點就是通過SubString函式得到split的效果。

'103,105,106,107'

翻譯的表結構是這樣子的
在這裡插入圖片描述
需要通過dic_kind和dic_code兩個資料找到對應的翻譯欄位。
可以看到翻譯字典表裡的資料只支援一個一個數據的翻譯。系統裡是在java後臺通過分割字串進行翻譯,這裡由於是用logstash同步資料,所以只能在sql裡直接翻譯。

想法

對字串進行分割,然後對每一個分割的資料進行翻譯,隨後再把翻譯後的資料新增在一起返回。

函式程式碼

CREATE DEFINER=`root`@`localhost` FUNCTION `translate`(dat VARCHAR(255),type VARCHAR(255)) RETURNS varchar(255) CHARSET utf8mb4
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE str VARCHAR(255);
DECLARE returnStr VARCHAR(255);
	while i <= (LENGTH(dat)-LENGTH
(REPLACE(dat,',','')) + 1) DO SELECT DIC_DESC from ts_dic where DIC_CODE = SUBSTRING_INDEX(SUBSTRING_INDEX(dat,',',i),',',-1) AND DIC_KIND = type into str; SET returnStr = CONCAT_WS(',',returnStr,str) ; SET i=i+1; END WHILE; RETURN returnStr; END

解釋:

LENGTH(dat)-LENGTH(REPLACE(dat,',','')
) + 1

LENGTH:獲取字串長度
REPLACE(p1,p2,p3):替換函式,p1是要替換的字串,p2:要被替換掉的字串,p3:用什麼來替換
所以這一句程式碼的作用就是為了得到字串被分割後的長度,如果是103,105,106,107的話,最後的值就是4.因為替換掉的只有中間的三個字元,所以最後要加一才是對應的長度。

解釋

SELECT DIC_DESC from ts_dic where DIC_CODE = SUBSTRING_INDEX(SUBSTRING_INDEX(dat,',',i),',',-1) AND DIC_KIND = type into str;

這句是精華
SUBSTRING_INDEX(p1,p2,p3):對字串進行擷取,p1是要被擷取的字串,p2是從這個字元開始擷取。
p3如果是正數,則從左往右數第幾個p2的位置。如果是1,則是從左往右數第一個p2的位置開始往左擷取,如果是2,便是從左往右數第二個p2的位置開始往左擷取。
p3如果是負數,則是從右往左數第幾個p2的位置開始往右擷取。
例子1:
SUBSTRING_INDEX(‘103,105,106,107’ , ‘,’ ,1) 之後得到的便是103
再經過外層的分割 SUBSTRING_INDEX(‘103’ , ‘,’ ,-1) 得到的還是103
例子2:
SUBSTRING_INDEX(‘103,105,106,107’ , ‘,’ ,2) 之後得到便是103,105
再經過外層的分割 SUBSTRING_INDEX(‘103,105’ , ‘,’ ,-1) 得到的便是105
這樣通過SUBSTRING_INDEX 函式便能得到Java後臺split的效果。

這樣拿到對應的編碼之後就可以去對應的表裡尋找對應的翻譯欄位了。最後將查到的資料放入到str

最後將strreturnStr拼接到一起返回。這裡用到的CONCAT_WS 拼接函式可以保證如果一方為空,最終結果不會為空。
這樣函式就可以使用了,只需要傳入對應的編碼值還有對應的dic_kind便可以對其進行翻譯。

SELECT translate('104,106', 'crClass') as title

結果
在這裡插入圖片描述