在项目中遇到了产品的分类,类别较多并且可以多选,此种情况的查询 like 并不适用,查询后使用 find_in_set(),对like 与find_in_set()做了浅显的研究。
查询type为1的数据,简略表如下:
id | type |
---|---|
1 | 1,2,3 |
2 | 2,8,9 |
3 | 3,10,11 |
一、like 查询的限制
like查询:
SELECT * FROM `test` WHERE type LIKE '%1%';
查询到的数据为:
id | type |
---|---|
1 | 1,2,3 |
3 | 3,10,11 |
显然此时是不合理的,合理的结果应该只有id=1的数据。
原因
like 是模糊查询,在前后均有通配符‘%’的情况下,查询的数据只要含有‘1’就会被输出
二、FIND_IN_SET()
1、查询 find_in_set()的输出
SELECT FIND_IN_SET(3,'1,2,3')
结果如下:
实质上find_in_set()查询的是字符串1在字符串2(逗号隔开)中的位置,不存在则返回false(0)
2、find_in_set()在where中的使用与使用范围
SELECT * FROM test WHERE FIND_IN_SET(1,type)
此时查询的结果正确
find_in_set()使用范围:find_in_set()适用于字段中含有多个值且值与值之间使用逗号隔开的情况
三、symfony下使用FIND_IN_SET()
symfony(doctrine)的函数并不支持find_in_set,需要引入第三方bundle:
composer require beberlei/DoctrineExtensions
并在配置文件内引入函数:
symfony4:..\config\packages\doctrine.yml
引用函数内容在../vendor/beberlei/DoctrineExtensions/config/mysql.yml中有
查询:
注意:在symfony(doctrine)内必须跟 !=0, 或者 >=0, 因为上文提过实质查询的是字符串2在1中的位置,否则会报错
FIND_IN_SET( :type, p.type) != 0