Mysql: Look for specific letter in comma separated list - mysql

I've got a column with the possible a,b,c and city.
One, many or all of them may occur on each row as comma separated.
I'm trying to do a query where I look for all rows that contain c but not city.
I've tried LIKE %c% and LIKE c but that would not return correct results. I'm starting to look towards Regexp but it feels like there must be a better solution.
Any thoughts on this?

Use FIND_IN_SET for matching comma-separated values:
select * from TableName where FIND_IN_SET("c", column)

Related

MYSQL select all record if contains specific number

I have a small problem, I have a table like this:
id|name|group|date_created
1|Volvo|1,3|06-04-2020 10:00:00
2|Audi|3|06-04-2020 10:00:00
etc....
Now I wish I could get all the records that have the value 1 inside the group column.
I tried LIKE "%1%", but I don't think it's a good query. Can you address me?
SELECT id FROM cars WHERE group LIKE '%1%'
The problem with your query is that it would wrongly match '1' against a list like '45,12,5' for example.
One method is to add commas on both ends before searching:
where concat(',', `group`, ',') like '%,1,%';
But in MySQL, it is much more convenient to use string function find_in_set(), whose purpose is just what you are looking for, ie search for a value in a comma-separated list:
select id from cars where find_in_set('1', `group`) > 0
Notes:
you should fix your data model, and have a separated table to store relationship between ids and groups, with each tuple on a separate row. Related reading: Is storing a delimited list in a database column really that bad?
group is a reserved word in MySQL, so not a good choice for a column name (you would need to surround it with backticks everytime you use it, which is error-prone)

Finding Partial Duplicates in MySQL (Keys with last 6 characters the same)

Got stuck on this one, know it should be simple.
But I have a list of unique IDs that looks like AB123456, XY584234, CDE987654. The last six characters mean something, so I need to find all rows that have the same last six characters as another (substring).
So ABCD1234 would match XYCD1234, and return the both of them. Need to run this on the whole database and get all the matches, preferably with the matches next to each other.
Is that possible?
You can do this with group by and right. The following returns a list of all ids that look similar:
select right(id, 6), group_concat(id)
from table t
group by right(id, 6);
You might want to add:
having count(*) > 1
If you don't want singletons.
Please use below query to get your result.
select * from tablename where right(columnname,6)= value

string search in MySQL Query

My MySQL field having skills field(string) like,
1)php,mysql
2)java
3)java,c
I need to select the column with skills field condition. Condition may be Like,
skills="php" // o/p => 1st column
or
skills = "mysql,c" // o/p => 1st and 3rd column
How I can write Query.? Here im using PHP.
One way to do it
SELECT *
FROM table1
WHERE skills LIKE '%mysql%'
OR skills LIKE '%c%'
SQLFiddle
It would be much easier if you'd normalized your data
Use a procedure like this one:
Split comma separated values from one column to 2 rows in the results. MySQL
To split your csv skills field into a temp table with rows for each skill
Then do the same thing with your search parameters (which I assume is also csv string passed in)
Then simply apply a JOIN over the two results and get the DISTICT Id.
there are many solutions for splitting a comma separated string in MySQL (though it's not particularly good at this task)... if you can't properly normalize the data then you can't very well complain about inefficient query routines.

Delete rows with Sub Query?

I can't seem to get the SQL to work when using LIKE
DELETE FROM `customer_numbers`
WHERE number NOT LIKE (SELECT number FROM number_part)%
Basically delete all the rows from constomer_numbers table if number does not contain in number_part table
Example:
customer_numbers.number = 0559354544 and number_part.number = 05593 - it shouldn't delete it.. However if 05593 does not contain in customer_numbers.number then delete row from customer_numbers table.. It should match first 5 digits from number_part
You can't use not like with a list (in most databases, I'm pretty sure this is true in mysql).
Instead, you can use a correlated subquery:
DELETE FROM `customer_numbers`
WHERE not exists (SELECT number FROM number_part
where customer_numbers.number like concat(number, '%')
)
Your query is rather broken. In at least two ways:
Your subquery returns multiple rows, but is in a place where it looks like you expect a single result.
You need your LIKE string to be quoted.
2 is probably easy to fix. Try:
... WHERE number LIKE CONCAT((SELECT ... LIMIT 1),'%');
1 is really your problem, though. If you run your subselect as a single command, I expect you'll get multiple rows, right? How do you expect to treat a list of numbers (let's say, 1, 2, 3, 4, 5) as part of a LIKE string?
What I'm guessing you're hoping for is something like LIKE '1%' OR LIKE '2%' OR LIKE '3%'..., etc... No?
At any rate, if you can tell us more precisely what you're trying to do, we can probably help you solve your problem better.
As your question is worded, all I can say is: It doesn't work that way.
You named your fields numbers but it seems like they are character values because of the leading 0s so I am going to assume they are character fields.
If your part number is always going to be 5 characters long then you can do the following:
DELETE FROM `customer_numbers`
WHERE substring(number,1,5) NOT IN (SELECT number FROM number_part)
You can't do a LIKE on a numerical field.
You can't do an equality on a sub-select that isn't DISTINCT.
You must use "IN".
DELETE FROM `customer_numbers` WHERE number NOT IN (SELECT number FROM number_part)
How about something like this:
DELETE FROM customer_numbers WHERE number NOT IN (SELECT number FROM number_part)

MySQL Reg ex, need to match phrases in any order

I am using a MySQL Database to search through a list of categories. My query is:
select * from cat where name REGEXP('(region_Long Island)+(.)*(sport_Outdoor Track)');
where the values "region_Long Island" and "sport_Outdoor Track" are passed in. I need to be able to match these categories, regardless of the order they are in. In the table, it is possible to have various combinations of these two categories. I need to match any records that have both of these categories, regardless of what order they are listed in.
I am not able to change the query itself, only modify what is passed into th REGEXP function.
Thank you
If you can use only a single regexp and you can't change the SQL query, then to match both A and B in any order, you need a regexp that matches AB or BA:
'region_Long Island.*sport_Outdoor Track|sport_Outdoor Track.*region_Long Island'
Re your comment:
What about cases where there are more than two, in any particular order?
If you had patterns A, B, and C any you needed to find all three in any order, you'd need a regexp that matches ABC, ACB, CAB, CBA, BAC, or BCA. This quickly starts to look like you need n! permutations if you have n patterns.
That's why a single regular expression is not a good solution for these cases. You're going to have to use another approach.
I am not able to change the query itself, only modify what is passed into the REGEXP function.
Sorry, that's not going to work.
SELECT *
FROM cat
WHERE name RLIKE 'region_Long Island'
AND name RLIKE 'sport_Outdoor Track'