MySQL - 将列表作为字段使用 WHERE IN 语句

3
我有一个字段('roles'),它有这些值。
        roles
row_1: 1,2,3,5
row_2: 2,13

I do this:

SELECT * FROM bloques WHERE 2 IN (roles)

只查找行2,因为它以2开头。

LKE选项不起作用,因为如果我查找1

SELECT * FROM bloques WHERE roles LIKE '%1%'

它可以给我两行数据。


你的需求是什么?我不明白... 你期望什么值?为什么? - nawfal
3
不要在意下面的所有答案,唯一有效的答案是:深入了解数据库规范化并废弃你的数据库设计! - fancyPants
请选出包含一列中精确数字的行,该列中的数字集合已用分隔符进行分隔。 - Sir Rufo
5个回答

3

FIND_IN_SET函数可以帮助你:

SELECT FIND_IN_SET('b','a,b,c,d');

针对您的代码:

SELECT * FROM bloques WHERE FIND_IN_SET(2,roles);

另外,我建议您将模式移动到第一范式


0

0
SELECT 
  * 
FROM 
  bloques 
WHERE 
  roles LIKE '%,2,%' 
  OR roles LIKE '2,%' 
  OR roles LIKE '%,2'

第一种情况将给出所有包含2在集合中间的情况,第二种情况是2开始集合,第三种情况是2结束集合。这可能非常低效,但应该可以工作。


你需要第四种情况来处理单独的“2”。有更好的方法来解决这个问题。 - raina77ow

0

使用FIND_IN_SET()函数

试试这个:

SELECT * FROM bloques WHERE FIND_IN_SET(1, roles);

或者

SELECT * FROM bloques 
WHERE CONCAT(',', roles, ',') LIKE '%,1,%';

0
你可以在这里使用这个正则表达式:
SELECT * FROM bloques 
  WHERE roles REGEXP '[[:<:]]2[[:>:]]';

...或者,在更一般的情况下:

SELECT * FROM bloques 
  WHERE roles REGEXP CONCAT('[[:<:]]', :your_value, '[[:>:]]');

你需要使用这些看起来很奇怪的符号,因为它们匹配单词边界,防止在“23”和“32”处出现“2”的匹配。

问题是查询只是使用非规范化字段导致的问题的开始。我建议使用SET类型(如果选项数量有限且较少)或者更好的方式是使用连接表来存储m-n关系。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接