背景
最近在优化项目遇到一个场景:数据库表中某个字段存储是多个字符串连接的;
如 合同1(contract1) 对应多个联系人:linker1,linker2,这样 合同A 的Id 对应订单的存储就是 order1,order2;
我们需要查询 linker2 和 多少个合同有关;怎么办呢?使用 find_in_set 函数
简述
MySQL手册中find_in_set函数的语法:
FIND_IN_SET(str,strlist)
str 要查询的字符串
strlist 字段名 参数以”,”分隔 如 (1,2,3,4)
查询字段(strlist)中包含(str)的结果,返回结果为null或记录
假如字符串str在由N个子链组成的字符串列表strlist 中,则返回值的范围在 1 到 N 之间。
一个字符串列表就是一个由一些被 ‘,’ 符号分开的子链组成的字符串。
如果 第一个参数是一个常数字符串,而第二个是 SET 列,则FIND_IN_SET() 函数被优化,使用比特计算。
如果str不在strlist 或strlist 为空字符串,则返回值为 0 。
若任意一个参数为NULL,则返回值为 NULL。
注意:这个函数在第一个参数包含一个逗号(‘,’)时将无法正常运行,第二个参数必须以","分割开
简单使用
select * from contract where FIND_IN_SET(id, '1,2,3,4,5');
id 是一个表的字段,然后每条记录分别是id等于1,2,3,4,5的时候。
使用find_in_set函数一次返回多条记录
是不是发现和 in 一样啊 (集合)
select * from treenodes where id in (1,2,3,4,5);
和 in 的区别
CREATE TABLE `user_info` (
`id` int(8) NOT NULL auto_increment,
`name` varchar(16) NOT NULL,
`friends` varchar(32) NOT NULL,
PRIMARY KEY (`id`)
);
INSERT INTO `user_info` VALUES (1, 'name1', 'xiaowang,xiaohai,xiaoyang');
INSERT INTO `user_info` VALUES (2, 'name2', 'xiaotong,xiaodao,xiaocheng');
INSERT INTO `user_info` VALUES (3, 'name3', 'xiaotong,xiaodao,xiaohai');
现在搜索 friends 中包含 xiaodao 的记录,使用 in
select * from user_info where 'xiaodao' in(friends);
查询不到任何数据,因为 in 函数 只有当 friends 字段等于 xiaodao 的时候才可以 搜索的到记录
现在看看 find_in_set 函数
select * from user_info where find_in_set( 'xiaodao', friends);
这样就显示关于 xiaodao 的记录了。
和 like 的区别
刚才的例子有的人为啥不用 like;没错,使用like也是可以查询出来的,只是在使用模糊匹配可能查询出错误数据
INSERT INTO `user_info` VALUES (4, 'name1', 'xiaowang,xiaohai,xiaodao2');
INSERT INTO `user_info` VALUES (5, 'name1', 'xiaowang,xiaohai,1xiaodao');
如果使用like 查询的话
select * from user_info where friends like '%xiaodao%';
这样就会把 不相关的xiaodao2 ,1xiaodao 查询出来