在MySQL表中,我有一个名为“Tag”的字段,可能包含多个以逗号分隔的值。
我想选择Tag字段包含值“1”的行。
我如何编写MySQL语句,以便选择Tag值为“1”和“1,Cars”的行, 但是排除Tag值为“17”和“17,Cars”的行?
我正在使用“LIKE”运算符的问题,但是会导致选择所有这四行。
感谢。
答案 0 :(得分:2)
FIND_IN_SET将搜索以逗号分隔的列表,例如:
SELECT FIND_IN_SET('b','a,b,c,d');
在这种情况下,某些内容符合
SELECT tag FROM table
WHERE FIND_IN_SET('1', tag) > 0
应该这样做。
编辑:当找不到匹配时它实际返回0,因此NULL检查错误。
答案 1 :(得分:1)
您可能需要执行类似
的操作WHERE Tag LIKE "1,%"
OR Tag LIKE "%,1,%"
OR Tag LIKE "%,1"
OR Tag = "1"
然后应该涵盖所有选项。
您可能希望更多地使用Regular Expressions
答案 2 :(得分:1)
如果您只想选择其中包含1的那些,您可以使用:
where colm like '1,%'
or colm like '%,1,%'
or colm like '%,1'
or colm = '1'
但是你应该知道这将是一个性能杀手。如果曾发现自己需要操作小于列的内容,则会严重设置数据库架构。 原因上述查询无法正常执行的原因是无法使用索引快速找到满足查询的行。它需要一个完整的表或索引扫描来获取行。
最好重新设计架构,将逗号分隔的东西分成另一个表中的行。
一个例子就是:
PrimaryTable:
id integer primary key
other_stuff varchar(250)
SecondaryTable:
primary_id integer references PrimaryTable(id)
int_val integer
char_val varchar(20)
primary key (primary_id,int_val)
index (int_val)
这将允许您编写令人眼花缭乱的快速查询,而不是您提议的缓慢的内容:
select p.id, p.other_stuff
from PrimaryTable p, SecondaryTable s
where p.id = s.primary_id
and s.int_val = 1;
(或等效的显式连接语法)。
此解决方案运行速度更快的原因是它可以使用SecondaryTable.int_val
上的索引快速检索相关行和两个表的主键进行交叉匹配。
答案 3 :(得分:0)
您可以将word boundaries与REGEX一起使用:
SELECT TAG
FROM TABLE
WHERE TAG REGEXP '[[:<:]]1[[:>:]]';