我知道SQL中的LIKE
函数,但我需要做一些稍微复杂的事情。
在我的表people
中,我有一个名为banned
的文本字段,其中存储了一个由@
分隔的所有禁止名称的字符串。让我们banned = Roger@Bobjob@Billy
说我想检查名称Bob
是否出现
SELECT * FROM people WHERE banned LIKE '%$Bob%'
由于字符串中的Bobjob
,这可能会找到结果。
有什么方法可以让它只在@
分隔符中找到全名吗?
答案 0 :(得分:2)
忘记在其中任何一个中使用索引....但由于你使用的是%var%,我假设你已经预料到了。
我们可以在禁止的开始和结束时连接@,以便每个名字都被@s包围,然后在名称搜索中使用@。 (期望在其中没有名字@并且期望被禁止不以@开头也不会结束(如果他们这样做,那么下面的内容真的无关紧要))
Where concat('@', banned,'@') like '%@Bob@%'
通过将@转换为a来使用find in set,如果结果为> 1然后就找到了。
find_in_set('Bob',replace(banned,','))>1
答案 1 :(得分:2)
如果您知道列表总是由2个或3个名称组成(如您的评论中所述),最直接的方法是检查所有3种可能的情况:
SELECT *
FROM people
WHERE list LIKE 'bob@%' /* name in first position */
OR list LIKE '%@bob@%' /* name in second position */
OR list LIKE '%@bob' /* name in third, final position */
答案 2 :(得分:1)
你应该使用concat来构建一个类似于vars和@
的条件SELECT * FROM people WHERE banned LIKE concat('%@%', '$Bob','%@%')
答案 3 :(得分:1)
这不是一个理想的数据结构,但暂时搁置一边:
如果您可以将分隔符更改为逗号,则mysql具有内置函数:FIND_IN_SET
SELECT * FROM people WHERE FIND_IN_SET('Bob', list);
否则,您可以进行正则表达式匹配。
SELECT * FROM people WHERE list REGEXP '(^|@)Bob($|@)';
这些都不一定非常高效,所以我不会在大型数据集上尝试它。
答案 4 :(得分:0)
它可能不是最好的数据库体系结构,但您可能会使用正则表达式来实现这样的目的
SELECT * FROM people WHERE banned RLIKE '(^|@)Bob($|@)'