Replace text in SQL - mysql

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

Related

Mysql regex search over an array of phone numbers

Need help in executing a query over a customer database on a field named phone.
select * from customers where phone REGEXP '123456|565834'
I need a way to select the matched portion of regex matched in select clause.
The final results should be something like
Name Matched Phone
Naveen 123456 12345678
Naveen2 123456 123456789
Arun 565834 9565834
Arun2 565834 10565834
P.S. This has to be one query and there is no other unique key to be grouped by with
Use INSTR function of MySQL.
Ex. INSTR(regex, phone)
SELECT SUBSTRING('123456|565834',INSTR('123456|565834',phone),10)
FROM customers
WHERE phone REGEXP '123456|565834';
Doc: INSTR function
You may use a CASE expression here:
SELECT
Name,
CASE WHEN Phone REGEXP '123456' THEN '123456'
WHEN Phone REGEXP '565834' THEN '565834' END AS Matched,
Phone
FROM customers
WHERE
phone REGEXP '123456|565834';
Note that you don't necessarily need to use REGEXP in this case, LIKE probably would have sufficed. But using REGEXP is easier to read IMO, and also it lets you handle more complex logic, should you need to in the future.
If you're not constrained to only use mysql, then may try with shell script + mysql to pass the map values and search - Not sure understood the requirement correctly.
search="5672C";
mysql <connection details> -e "select fields, \"$search\" as matched from customers where phone like \"%$search%\";"
We can loop the map strings and achieve.

MySQL - need to find records without a period in them

I've been to the regexp page on the MySQL website and am having trouble getting the query right. I have a list of links and I want to find invalid links that do not contain a period. Here's my code that doesn't work:
select * from `links` where (url REGEXP '[^\\.]')
It's returning all rows in the entire database. I just want it to show me the rows where 'url' doesn't contain a period. Thanks for your help!
SELECT c1 FROM t1 WHERE c1 NOT LIKE '%.%'
Your regexp matches anything that contains a character that isn't a period. So if it contains foo.bar, the regexp matches the f and succeeds. You can do:
WHERE url REGEXP '^[^.]*$'
The anchors and repetition operator make this check that every character is not a period. Or you can do:
WHERE LOCATE(url, '.') = 0
BTW, you don't need to escape . when it's inside [] in a regexp.
Using regexp seems like an overkill here. A simple like operator would do the trick:
SELECT * FROM `links` WHERE url NOT LIKE '%.%
EDIT:
Having said that, if you really want to negate regexp, just use not regexp:
SELECT * FROM `links` WHERE url NOT REGEXP '[\\.]';

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*%'

Mysql query, contains a string then 3 numbers in email

I have a mysql database with a table that contains an email address entered by website users.
How would I select all records where the email field contains any number of characters, then 3 numbers and #yahoo.com
i.e. testemail639#yahoo.com
A simple way would be to use REGEXP in your SELECT statements.
SELECT * FROM records WHERE email REGEXP '^\w+\d{3}\#.*$'
The above statement is untested, but should lead you down a better road.
SELECT * FROM table WHERE email REGEXP '[0-9]{3}#yahoo\.com'
Try this
SELECT * FROM records WHERE email REGEXP '^\w+([\.-]?\w+)?([0-9]{3})#\w+([\.-]?\w+)*(\.\w{2,4})+$'
^\w+([\.-]?\w+)?([0-9]{3})#\w+([\.-]?\w+)*(\.\w{2,4})+$ strictly checks string followed by 3 numbers pattern in the email containing no spaces

mysql select query - to match one field with the other field

I am trying to find records that has the following scenario.
ID | name | email
1 Robert robert#gmail.com
2 William bill#gmail.com
3 Michael michael#gmail.com
4 Micahel mike#gmail.com
Based on the above table, I want to find the records where the "name" is contained in the "email field", here record 1 and 3 should be the output and not 2 and 4. Is there any way I can do this comparison?
I tried reading about regex but couldn't find anything. If it's comparison of same value, it will be straightforward, but I am not having any clue for this one. I thought of LIKE but looks like this cannot have field names.
The exact syntax will depend on how you want to define the relationship.
Are you looking for the name anywhere in the email address? (This will be slow)
select id,name,email
from your_table
where email like concat('%',name,'%')
Just at the beginning of the email address?
select id,name,email
from your_table
where email like concat(name,'%')
Just before the # sign?
select id,name,email
from your_table
where email like concat(name,'#%')
You can use LIKE, you just have to use it in combination with CONCAT.
SELECT
ID,
name,
email
FROM
yourTable
WHERE
email LIKE CONCAT(name, '%');
The CONCAT will return a string which can be used to match against email via LIKE.
This should work
SELECT * FROM table WHERE email LIKE (CONCAT('%',name,'%'))
select * from your_table where lower(substring_index(email,'#',1))=lower(name)