我有一个具有此值的字段(“角色”)
roles
row_1: 1,2,3,5
row_2: 2,13
我这样做:
SELECT * FROM bloques WHERE 2 IN (roles)
并且只找到 row_2,因为它从 2 开始
LIKE 选项不起作用,因为如果我找到 1
SELECT * FROM bloques WHERE roles LIKE '%1%'
,它给了我两行。
我有一个具有此值的字段(“角色”)
roles
row_1: 1,2,3,5
row_2: 2,13
我这样做:
SELECT * FROM bloques WHERE 2 IN (roles)
并且只找到 row_2,因为它从 2 开始
LIKE 选项不起作用,因为如果我找到 1
SELECT * FROM bloques WHERE roles LIKE '%1%'
,它给了我两行。
FIND_IN_SET函数可以帮助您:
SELECT FIND_IN_SET('b','a,b,c,d');
对于您的代码:
SELECT * FROM bloques WHERE FIND_IN_SET(2,roles);
另外,我建议您将架构移至1NF
你能用正则表达式吗?http://dev.mysql.com/doc/refman/5.1/en/regexp.html
否则,您可以在行的开头和结尾添加逗号。
select * from mytable where ',' + roles + ',' like '%,2,%'
SELECT
*
FROM
bloques
WHERE
roles LIKE '%,2,%'
OR roles LIKE '2,%'
OR roles LIKE '%,2'
第一种情况将为您提供 2 位于集合中间的所有情况,第二种情况是 2 开始集合,第三种情况是 2 结束集合。这可能是非常低效的,但它应该工作。
使用FIND_IN_SET()函数
尝试这个:
SELECT * FROM bloques WHERE FIND_IN_SET(1, roles);
或者
SELECT * FROM bloques
WHERE CONCAT(',', roles, ',') LIKE '%,1,%';
您可以在此处使用此正则表达式:
SELECT * FROM bloques
WHERE roles REGEXP '[[:<:]]2[[:>:]]';
...或者,在更一般的情况下:
SELECT * FROM bloques
WHERE roles REGEXP CONCAT('[[:<:]]', :your_value, '[[:>:]]');
您需要使用这些看起来很奇怪的东西,因为它们匹配单词边界 - 防止匹配 '2' 出现在 '23' 和 '32'。)
问题是查询只是使用非规范化字段引起的麻烦的开始。我建议使用 SET 类型(如果选项数量有限且很少),或者更好的是,使用联结表来存储 mn 关系。