Is there a way to combine IN and LIKE in MySQL? - mysql

I'm currently running a query like this:
SELECT *
FROM email
WHERE email_address LIKE 'ajones#%'
OR email_address LIKE 'bsmith#%'
OR email_address LIKE 'cjohnson#%'
The large number of OR's bothers me. Is there a way to condense this up with something akin to an IN operator, e.g.:
SELECT *
FROM email
WHERE email_address LIKE ('ajones#%', 'bsmith#%', 'cjohnson#%')
Or is this just wishful thinking?

You can use RLIKE operator (synonym for REGEXP) as well.
SELECT *
FROM email
WHERE email_address RLIKE 'ajones#|bsmith#|cjohnson#'
There might be some performance penalty due to regex matching, but for simple patterns or small sets it should be not an issue.
For more on RLIKE see http://dev.mysql.com/doc/refman/5.1/en/regexp.html#operator_regexp

Here's what I recommend: Extract the part of the email address before the # and use that before IN:
SELECT * FROM `email`
WHERE LEFT(`email_address`, LOCATE('#', `email_address`) - 1)
IN ('ajones', 'bsmith', 'cjohnson')

Related

Replace text in SQL

I have a field called EMAIL_ADDRESS. One of the records would be:
john#gmail.com, mike#gmail.com, joe#yahoo.com, george#yahoo.com, fred#gmail.com
I wan to remove all yahoo addresses in my SELECT query to get:
john#gmail.com, mike#gmail.com, fred#gmail.com
If I use
REPLACE(SM.SCORECARD_EMAIL_ADDRESS, 'joe#yahoo.com,', '')
this works.
If I want to remove ALL yahoo email addresses this doesn't work:
REPLACE(SM.SCORECARD_EMAIL_ADDRESS, '%#yahoo.com,', '')
because wildcards don't seem to work as it's looking for % in the string.
You should probably fix your table design and stop storing CSV lists of email addresses. Instead, get each email onto a separate record. As a short term fix, if you're running MySQL 8+, you may use REGEXP_REPLACE():
UPDATE yourTable
SET EMAIL_ADDRESS = REGEXP_REPLACE(
REGEXP_REPLACE(EMAIL_ADDRESS, '(, )?\\S+#yahoo\\.com,?', ','), '^,+|,+$', '')
WHERE EMAIL_ADDRESS LIKE '%#yahoo.com%';
If you don't need to udpate records but you want them only in the SELECT query you can use NOT LIKE operator
SELECT * FROM your_table WHERE email NOT LIKE '%yahoo.com'
So you get records that doesn’t match the like pattern

like clause doesn't work as it said in MySQL SQL

I have a table, such as
create table table1(
name varchar(32),
);
And there's some data in it. When I select like this:
select * from table1 where name like 'Jack2%';
there will be Jack2.
But if I select like this:
select * from table1 where name like 'Jack[0-9]%';
there will be nothing;
And I also tried regexp to subsitute like, but it also didn't work!
What's wrong?
You've confused two different pattern-matching mechanisms. SQL LIKE uses % to match anything and _ to match any single character; it does not have anything like [0-9] to match a digit. That looks like a character class from a regular expression.
Standard SQL has no support for regular expressions at all, but MySQL does - you just have to use RLIKE (or REGEXP, but that doesn't read as nicely IMO) instead of LIKE. But that means that you have to replace the % with the regular-expression equivalent .*, too.
SELECT * FROM table1 WHERE name RLIKE 'Jack[0-9].*';
Fiddle
MySQL REGEX
select * from Table1 where `name` REGEXP 'Jack[0-9]'
You can use RLIKE instead
SELECT * FROM table1 WHERE name RLIKE 'Jack[0-9].*';
And please note the the '%' operator won't work with RLIKE, you have to use a regular expression pattern like '.*' instead.

MySQL - WHERE IN with a list into a field

I have a field ('roles') with this values
roles
row_1: 1,2,3,5
row_2: 2,13
I do this:
SELECT * FROM bloques WHERE 2 IN (roles)
and only find row_2, because it starts by 2
The LIKE option doesn't work because if I find 1
SELECT * FROM bloques WHERE roles LIKE '%1%'
, it gives me both rows.
FIND_IN_SET function cal helps you:
SELECT FIND_IN_SET('b','a,b,c,d');
For your code:
SELECT * FROM bloques WHERE FIND_IN_SET(2,roles);
Also, I suggesto to you that move your schema to 1NF
Could you use REGEXP? http://dev.mysql.com/doc/refman/5.1/en/regexp.html
Otherwise, you could add commas to the front and end of your rows.
select * from mytable where ',' + roles + ',' like '%,2,%'
SELECT
*
FROM
bloques
WHERE
roles LIKE '%,2,%'
OR roles LIKE '2,%'
OR roles LIKE '%,2'
The first case will give you all cases where 2 is in the middle of a set, the second case is when 2 starts the set, and the third case is when 2 ends the set. This is probably terribly inefficient, but it should work.
You can use this regex here:
SELECT * FROM bloques
WHERE roles REGEXP '[[:<:]]2[[:>:]]';
... or, in more generic case:
SELECT * FROM bloques
WHERE roles REGEXP CONCAT('[[:<:]]', :your_value, '[[:>:]]');
You need to use these weird-looking things, as they match word boundaries - preventing match for '2' to occur at '23' and '32'. )
The problem is that query is only the beginning of the troubles caused by using denormalized field. I'd suggest using either SET type (if the number of options is limited and low) or, way better, junction table to store the m-n relationships.
Use FIND_IN_SET() function
Try this:
SELECT * FROM bloques WHERE FIND_IN_SET(1, roles);
OR
SELECT * FROM bloques
WHERE CONCAT(',', roles, ',') LIKE '%,1,%';

Query to select var REGEX MANY columns

Here is what I was want to Optimize this query
SELECT *
FROM users
where `username` like "%abc%"
or `name` like "%abc%"
or `email` like "%abc%"
This search get result from users where any of username , name , email like %abc%
So I tried to use in with like But
I was looking for mysql Like in and I have found this answer stackoverflow :Mysql like in
So the solution was regex
But I want to make the regex not use OR
I want to be like this
SELECT * from users where abc REGEXP 'username|name|email';
So the answer
Do you mean something like this? >>
SELECT * from users where CONCAT(username, ',', name, ',', email) REGEXP 'abc'

MySQL Like multiple values

I have this MySQL query.
I have database fields with this contents
sports,shopping,pool,pc,games
shopping,pool,pc,games
sports,pub,swimming, pool, pc, games
Why does this like query does not work?
I need the fields with either sports or pub or both?
SELECT * FROM table WHERE interests LIKE ('%sports%', '%pub%')
Faster way of doing this:
WHERE interests LIKE '%sports%' OR interests LIKE '%pub%'
is this:
WHERE interests REGEXP 'sports|pub'
Found this solution here: http://forums.mysql.com/read.php?10,392332,392950#msg-392950
More about REGEXP here: http://www.tutorialspoint.com/mysql/mysql-regexps.htm
The (a,b,c) list only works with in. For like, you have to use or:
WHERE interests LIKE '%sports%' OR interests LIKE '%pub%'
Why not you try REGEXP. Try it like this:
SELECT * FROM table WHERE interests REGEXP 'sports|pub'
You can also use REGEXP's synonym RLIKE as well.
For example:
SELECT *
FROM TABLE_NAME
WHERE COLNAME RLIKE 'REGEX1|REGEX2|REGEX3'
Don't forget to use parenthesis if you use this function after an AND parameter
Like this:
WHERE id=123 and(interests LIKE '%sports%' OR interests LIKE '%pub%')
Or if you need to match only the beginning of words:
WHERE interests LIKE 'sports%' OR interests LIKE 'pub%'
you can use the regexp caret matches:
WHERE interests REGEXP '^sports|^pub'
https://www.regular-expressions.info/anchors.html
Your query should be SELECT * FROM `table` WHERE find_in_set(interests, "sports,pub")>0
What I understand is that you store the interests in one field of your table, which is a misconception. You should definitively have an "interest" table.
Like #Alexis Dufrenoy proposed, the query could be:
SELECT * FROM `table` WHERE find_in_set('sports', interests)>0 OR find_in_set('pub', interests)>0
More information in the manual.
More work examples:
SELECT COUNT(email) as count FROM table1 t1
JOIN (
SELECT company_domains as emailext FROM table2 WHERE company = 'DELL'
) t2
ON t1.email LIKE CONCAT('%', emailext) WHERE t1.event='PC Global Conference';
Task was count participants at an event(s) with filter if email extension equal to multiple company domains.