简体   繁体   English

在MySQL字段中查询LIKE字符串

[英]Query MySQL field for LIKE string

I have a field called 'areasCovered' in a MySQL database, which contains a string list of postcodes. 我在MySQL数据库中有一个名为“ areasCovered”的字段,其中包含邮政编码的字符串列表。

There are 2 rows that have similar data eg: 有两行具有相似的数据,例如:

Row 1: 'B*,PO*,WA*'
Row 2: 'BB*, SO*, DE*'

Note - The strings are not in any particular order and could change depending on the user 注意-字符串不按任何特定顺序排列,并且可能会因用户而异

Now, if I was to use a query like: 现在,如果要使用类似以下的查询:

SELECT * FROM technicians WHERE areasCovered LIKE '%B*%'

I'd like it to return JUST Row 1. However, it's returning Row 2 aswell, because of the BB* in the string. 我希望它返回JUST Row1。但是,由于字符串中的BB *,它也将返回Row 2。

How could I prevent it from doing this? 我如何防止它这样做?

The key to using like in this case is to include delimiters, so you can look for delimited values: 在这种情况下使用like的关键是包括定界符,因此您可以查找定界的值:

SELECT *
FROM technicians
WHERE concat(', ', areasCovered, ', ') LIKE '%, B*, %'

In MySQL, you can also use find_in_set() , but the space can cause you problems so you need to get rid of it: 在MySQL中,您也可以使用find_in_set() ,但是空格可能会引起问题,因此您需要摆脱它:

SELECT *
FROM technicians
WHERE find_in_set('B', replace(areasCovered, ', ', ',') > 0

Finally, though, you should not be storing these types of lists as strings. 最后,尽管如此,您不应该将这些类型的列表存储为字符串。 You should be storing them in a separate table, a junction table, with one row per technician and per area covered. 您应该将它们存储在单独的表(联结表)中,每个技术人员和每个区域均覆盖一行。 That makes these types of queries easier to express and they have better performance. 这使得这些类型的查询更易于表达,并且具有更好的性能。

You are searching wild cards at the start as well as end. 您在开头和结尾都在搜索通配符。

You need only at end. 您只需要最后。

SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'

Reference: 参考:

Normally I hate REGEXP. 通常我讨厌REGEXP。 But ho hum: 但是哼哼:

SELECT * FROM technicians 
WHERE concat(",",replace(areasCovered,", ",",")) regexp ',B{1}\\*';

To explain a bit: 解释一下:

Get rid of the pesky space: 摆脱讨厌的空间:

select replace("B*,PO*,WA*",", ",",");

Bolt a comma on the front 在前面插入逗号

select concat(",",replace("B*,PO*,WA*",", ",","));

Use a REGEX to match "comma B once followed by an asterix": 使用REGEX匹配“逗号B,后跟一个星号”:

select concat(",",replace("B*,PO*,WA*",", ",",")) regexp ',B{1}\\*';

I could not check it on my machine, but it's should work: 我无法在我的机器上检查它,但是应该可以使用:

SELECT * FROM technicians WHERE areasCovered <> replace(areaCovered,',B*','whatever')

In case the 'B*' does not exist, the areasCovered will be equal to replace(areaCovered,',B*','whatever'), and it will reject that row. 如果'B *'不存在,areaCovered等于replace(areaCovered,',B *','whatever'),它将拒绝该行。 In case the 'B*' exists, the areCovered will NOT be eqaul to replace(areaCovered,',B*','whatever'), and it will accept that row. 如果'B *'存在,则areCovered不会被替换(areaCovered,',B *','whatever'),它将接受该行。

You can Do it the way Programming Student suggested 您可以按照编程学生的建议进行操作

SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'

Or you can also use limit on query 或者您也可以使用查询限制

SELECT * FROM technicians WHERE areasCovered LIKE '%B*%' LIMIT 1

%B*%在每一侧都包含%,这使其可以返回文本中任意位置上值包含B*所有行,但是您的要求是查找所有包含以B*开头的值的行,因此以下查询应工作。

SELECT * FROM technicians WHERE areasCovered LIKE 'B*%'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM