mySQL pattern matching a comma separated list - mysql

I have a mySQL table that contains restaurant information. Part of that information is a comma separated list of numbers that corresponds to the type of cuisine the restaurant serves. I'm having some problems getting the correct information out of the database. Table looks like
id businessName cuisine_id
1 Pizza Place 2,3,4,
2 Burger Place 12,13,14,
I came up with
SELECT * FROM restaurant WHERE cuisine_id LIKE "%2,%"
But that leaves me with the problem that it matches "2," "12," and 22,".
I also tried
SELECT * FROM restaurant WHERE cuisine_id LIKE "[^0-9]2,%"
But that returned nothing.
Any advice on how to write this expression?

Use regexp
SELECT * FROM restaurant WHERE cuisine_id REGEXP "(^|,)2,"
For num exact match,
SELECT * FROM restaurant WHERE cuisine_id regexp "(^|,)2(,|$)"
Note that ^, $ are mentioned as regex anchors which matches the start and end end of a line. This (^|,) will match either a start of a line or comma. So this ensured that the following pattern must be at the start or preceeded by comma.

There's no need to use regular expressions, you could use FIND_IN_SET string function:
SELECT * FROM restaurant WHERE FIND_IN_SET('2', cuisine_id)>0
or use CONCAT:
SELECT * FROM restaurant WHERE CONCAT(',', cuisine_id, ',') LIKE '%,2,%'
or better to normalize your database structure (is often not a good idea to store comma separated values in a single field)

Related

Understanding why querying cities with vowels at start and end doesnt work

Task:
Query the list of names from table which have vowels as both their first and last characters [duplicate].
I want to query the list of CITY names from the table STATION(id,city, longitude, latitude) which have vowels as both their first and last characters. The result cannot contain duplicates.
My query:
SELECT DISTINCT CITY
FROM STATION
WHERE CITY LIKE '[aeiou]%' AND '%[aeiou]'
I found this solution:
Select distinct city
from station
Where regexp_like(city, '^[aeiou].*[aeiou]$','i');
Why isn't my query working?
'[aeiou]' is a regex character class, which is not supported by operator LIKE. So your query won't do what you expect: it actually searches for a litteral string that starts with '[aeiou]' (and even if it was, you would need to repeat expression city like ... twice: city like ... and ... does not do what you expect either).
The solution you found uses regexp_like() with the following regex: ^[aeiou].*[aeiou]$, which means:
^ beginning of the string
[aeiou] one of the characters in the list
.* a sequence of 0 to N characters
[aeiou] one of the characters in the list
$ end of the string
Option 'i' makes the search case insensitive.
This works, but requires MySQL 8.0. If you are running an earlier version, consider using a REGEXP condition instead:
CITY REGEXP '^[aeiou].*[aeiou]$'

Cannot check if a field contains also number

I'm trying to check if a field in a specific table contains also number, in particular I have a record that have the field name which contains this value: Besëlidhja Lezhë vs. Tërbuni Pukë 1 - 1, so I'm trying to get also all the rows of that table that contains a number inside the field name. I tried:
SELECT * FROM `venue` where `name` like '%[0-9]%'
but this will return an empty result, any idea?
This should tell you if name contains any digit (not tested)
SELECT * FROM venue WHERE name REGEXP '[0-9]'
You can try using a Regular Expression that filters for names in your name column with numeric characters . For example:
SELECT * FROM DATA WHERE name REGEXP '[a-z]...[0-9]';
mySQL allows you to use regular expression as a filter !
This should select out for names like Tërbuni Pukë 1 - 1. If you want to practice regular expressions this is a great website to test whether you have the right regex. https://regex101.com/
Hope this helps !
I believe this should work:
SELECT *
FROM venue
WHERE name like '%0%' or name like '%1%' or name like '%2%' or name like '%3%'
and so on til you get to 9. I hope this helps

If value is present in stored text string

I have a table, one of the columns contains a text values, some of which are comma separated string, like this:
Downtown, Market District, Warehouse District
I need to modify my query to see is a given value matches this column. I decided that using IN() is the best choice.
SELECT *
FROM t1
WHERE myValue IN (t1.nighborhood)
I am getting spotty results - sometimes I return records and sometimes not. If there's a value in t1.nighborhood that matches myValue, I do get data.
I checked and there are no MySQL errors. What am I missing?
You can use FIND_IN_SET() to search a comma-delimited list:
SELECT *
FROM t1
WHERE FIND_IN_SET(myValue, REPLACE(t1.nighborhood, ', ', ','));
The REPLACE() is necessary to remove the extra spaces.
Another solution is to use regex to match your search value surrounded by commas if necessary:
SELECT *
FROM t1
WHERE t1.nighborhood REGEXP CONCAT('(^|, )', myValue, '(, |$)');
In general, it's bad design to store distinct values in a single column. The data should be normalized into a related table with a foreign key.

SQL - How to search for a string that contains backslash

I'm trying to find all entries that contain a backslash anywhere, like so:
SELECT * FROM animals WHERE bodyType LIKE '%\\%'
I also tried:
SELECT * FROM animals WHERE bodyType LIKE '%\\\\%'
and
SELECT * FROM animals WHERE bodyType LIKE '%\\\\\\\\%'
Neither worked. Anyone know how to do this?
I am running the commands in MySQL Quick Admin v1.5.4
This question has not answer.
You try to match searching of content with backslash on names of columns.
Your (a bit general) query
SELECT * FROM tableName WHERE columnName LIKE '%\\%'
will give you any result if content of any column will contain backslash. In this case your query is correct. But you cannot match name of any column.
I looked into some books I have and all they say the same: this will select all records written in column of chosen name that are containing backslash. But columns have to be chosen exactly (they cannot be selected by name with using of SQL query).

Query MySQL field for LIKE string

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?
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.
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. 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}\\*';
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.
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*% 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*%'