mySQL使用LIKE函数更精确

时间:2017-07-20 17:44:30

标签: php mysql sql

我知道SQL中的LIKE函数,但我需要做一些稍微复杂的事情。

在我的表people中,我有一个名为banned的文本字段,其中存储了一个由@分隔的所有禁止名称的字符串。让我们banned = Roger@Bobjob@Billy

说我想检查名称Bob是否出现

SELECT * FROM people WHERE banned LIKE '%$Bob%'

由于字符串中的Bobjob,这可能会找到结果。

有什么方法可以让它只在@分隔符中找到全名吗?

5 个答案:

答案 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($|@)'