MySQL 中 find_in_set 函数使用方法
FIND_IN_SET(str,strlist)
是一个 MySQL 库函数(大小写都支持),可以直接在 WHERE
中使用,主要作用就是判断前一个字符串常量是否在后者字符串列表变量中。返回在字符串列表匹配到的索引,索引从 1 开始计数,匹配不到返回 0。
在 sql 语句中,字段名是一个变量存在,而带入的参数就是常量。强调常量和变量是因为函数只接受这样的类型匹配,其他形式会报错或者查询不到结果。在这个函数里如果把字符串常量改成变量,sql 语句执行是查不到东西的(应该是函数内部做了判断),而如果都是常量那么返回结果是固定的——匹配项的索引或者 0。strlist
是一个字符串列表,或者更准确的说是一个字符串列表字符串,展现形式 apple,bird,cat
,多个字符串用英文逗号隔开(为什么不是中文逗号或者其他符号?因为这是人家做出来的软件,全世界通用)。
主要应用场景:多选分类的字段的单个分类匹配查询。比如一个对象录入分类时可多选,那么一般情况会把分类字段处理成 1,2,3
的形式。然而在展示页面搜索时,单个分类搜索会比较困难。因为分类 ID 通过常规的 like
进行匹配可能会出现错误匹配的情况。比如分类 ID 为 2,那么它会搜索出所有包含 2 的分类字段,1,2,3
、11,12,13
、21,22,23
...都会匹配成功,这显然是不对的。FIND_IN_SET(2, cateids)
就可以很精准并且轻松地解决。
当然,like
也是可以通过一些特别的处理,从而达到精准匹配效果。将存储字段内容首位加上 ,
(英文逗号),然后匹配参数处理成 ,2,
的形式。字段可以写入的时候就加上 ,
,然后匹配 catids like '%,2,%'
。也可以动态加上去,比如 CONCAT(',',catids,',') like '%,2,%'
。注意,MySQL 中字符串拼接可不是 +
或者 .
,而是 CONCAT()
函数。
多个分类匹配单选分类字段比较简单,可以直接用 IN 解决。如:catid IN (1,2,3)
。
如果前端应用场景是多个分类匹配多选分类字段呢?这种情况应该怎么处理呢?
当然可以用 FIND_IN_SET
,循环遍历的方式把需要的项拼接起来 FIND_IN_SET(2, cateids) AND FIND_IN_SET(3, cateids) AND...
。
还有另外一种方法,使用 REGXP 语句。REGXP 表示正则匹配,比 like 只能用 _
表示单个字符 和 %
表示 0 个或多个任意字符更加灵活。
使用例子:
CONCAT(',',catids,',') REGXP ',2,|,3,|,4,'