0

I have a field called 'areasCovered' in a MySQL database, which contains a string list of postcodes.

There are 2 rows that have similar data e.g:

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.

How could I prevent it from doing this?

6 Answers 6

4

The key to using like in this case is to include delimiters, so you can look for delimited values:

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:

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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:

1 Comment

But if the B* was in the middle of the string, it wouldn't find it? The order of the strings are not in alphabetic order. So it could be: 'DE*, B*, SO*'
1

Normally I hate 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":

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

Comments

0

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. In case the 'B*' exists, the areCovered will NOT be eqaul to replace(areaCovered,',B*','whatever'), and it will accept that row.

Comments

-1

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

Comments

-1

%B*% contains % on each side which makes it to return all the rows where value contains B* at any position of the text however your requirement is to find all the rows which contains values starting with B* so following query should do the work.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.