本篇文章主要介紹mysql中FIND_IN_SET函數(shù)用法,用來精確查詢字段中以逗號(hào)分隔的數(shù)據(jù)
以及其與 like 和 in 的區(qū)別
1.問題發(fā)現(xiàn)
之前在做工作任務(wù)時(shí)有這么一個(gè)需求:需要用接口所傳的服務(wù)商編號(hào)和所開通的產(chǎn)品類型查詢這張表中是否有此信息來做返回結(jié)果。
但公司的產(chǎn)品類型有多個(gè),每個(gè)服務(wù)商可能開通了多個(gè)不同的產(chǎn)品類型,存入產(chǎn)品類型時(shí)用的是一個(gè)字段,用逗號(hào)分隔開存儲(chǔ)。
這種場(chǎng)景下就需要精確查找其產(chǎn)品類型,我一開始想的是用 in 和 like 來實(shí)現(xiàn),但實(shí)際使用后并不是這種效果...請(qǐng)看下文講解~
2.解決問題
使用 in 實(shí)現(xiàn)
sql語句如下:
SELECT
agentNum
FROM
p4_agent_limit_merc_access a
WHERE
agentNum = #{agentNum} (傳入的服務(wù)商編號(hào))
AND #{productType} (傳入的產(chǎn)品類型)
IN(a.productType);
但實(shí)際上這樣寫是查不到數(shù)據(jù)的,只有a.productType 字段的值等于傳入的產(chǎn)品類型時(shí)(和IN前面的字符串完全匹配),這時(shí)查詢才有效,否則是查不到結(jié)果的,即使a.productType 里面包含傳入的產(chǎn)品類型。
使用 like 實(shí)現(xiàn)
sql語句如下:
SELECT
agentNum
FROM
p4_agent_limit_merc_access a
WHERE
agentNum = #{agentNum}
AND a.productType
LIKE concat('%',#{productType}, '%');
表面看上去這樣寫是沒問題的,但你細(xì)品一下,就知道問題很大,因?yàn)閘ike是廣泛的模糊查詢,但一個(gè)字符串里包含你要傳入的值時(shí),也能查出來,比如我們的產(chǎn)品類型productType有QPOS和POS,然而此次查詢的服務(wù)商只開通了QPOS產(chǎn)品,我卻傳入了POS這個(gè)類型,用上述語句查詢后也能查出這條結(jié)果,這就是問題所在,所以用like查詢出的范圍會(huì)更廣,這樣明顯不合理,不是我們想要的結(jié)果...
使用FIND_IN_SET函數(shù)實(shí)現(xiàn)
首先介紹下 FIND_IN_SET函數(shù):
FIND_IN_SET(str,strlist)
str 要查詢的字符串
strlist 字段名 參數(shù)以”,”分隔 如 (1,2,6,8)
查詢字段(strlist)中包含(str)的結(jié)果,返回結(jié)果為null或記錄
假如字符串str在由N個(gè)子鏈組成的字符串列表strlist 中,則返回值的范圍在 1 到 N 之間。 一個(gè)字符串列表就是一個(gè)由一些被 ‘,’ 符號(hào)分開的子鏈組成的字符串。如果第一個(gè)參數(shù)是一個(gè)常數(shù)字符串,而第二個(gè)是type SET列,則FIND_IN_SET() 函數(shù)被優(yōu)化,使用比特計(jì)算。 如果str不在strlist 或strlist 為空字符串,則返回值為 0 。如任意一個(gè)參數(shù)為NULL,則返回值為 NULL。這個(gè)函數(shù)在第一個(gè)參數(shù)包含一個(gè)逗號(hào)(‘,’)時(shí)將無法正常運(yùn)行。
介紹簡(jiǎn)單了解下就好,具體看怎么用,我的sql如下:
SELECT
agentNum
FROM
p4_agent_limit_merc_access a
WHERE
agentNum = #{agentNum}
AND FIND_IN_SET(#{productType},a.productType);
使用上述語句就可以精確查詢出數(shù)據(jù),實(shí)現(xiàn)需求。
再來看看FIND_IN_SET函數(shù)具體使用例子:
SELECT FIND_IN_SET('b', 'a,b,c,d'); 返回2
因?yàn)閎 在strlist集合中放在2的位置 從1開始
select FIND_IN_SET('1', '1'); 返回 就是1 這時(shí)候的strlist集合有點(diǎn)特殊 只有一個(gè)字符串 其實(shí)就是要求前一個(gè)字符串 一定要在后一個(gè)字符串集合中 才返回 大于0的數(shù)
select FIND_IN_SET('2', '1,2'); 返回2
select FIND_IN_SET('6', '1'); 返回0
3.總結(jié)
當(dāng) a.productType 字段是常量時(shí),則可以用 in 來實(shí)現(xiàn)。
當(dāng)其為變量時(shí),則必須要用FIND_IN_SET函數(shù)來實(shí)現(xiàn)了。
?更多精彩功能請(qǐng)關(guān)注我的個(gè)人博客網(wǎng)站:https://liujian.cool
??歡迎關(guān)注我的個(gè)人公眾號(hào):程序猿劉川楓