Find duplicate phone numbers (even if formatting differs) - mysql

I am using the following query to select duplicate phone numbers from a table.
SELECT id, REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( phone, "+", '' ) , ")", '' ) , "(", '' ) , "-", '' ) , ' ', '' ) AS strippedPhone
FROM `customers`
GROUP BY strippedPhone
HAVING count( strippedPhone ) >1
LIMIT 0 , 300
It looks ugly and does not consider the possibilities of alphanumeric character on the field having the phone number.
Any better ways?

This StackOverflow post MySQL strip non-numeric characters to compare has a solution that uses the NumericOnly function.
http://venerableagents.wordpress.com/2011/01/29/mysql-numeric-functions/

In my opinion you would be to normalize the phone numbers before you stored them in the database. Any sql query that is able to compare phone numbers regardless of format is going to be highly inefficient. Where as if you if you reformat the phone numbers before inserting them into the database checking for duplicate numbers is trivial.
If you want to do this on an existing database you will have to normalize the data in the database first but that only has to be done once.

Related

Search 2 columns for parts of string in MYSQL

I would like to search inside 2 columns for parts of a string. It's a backwards way of searching so I doubt it's possible.
I think part of it would have something to do with:
REPLACE( event_name, ' ', '')
and
REPLACE( venue_name, ' ', '')
to get rid of the space.
I also thought REGEX might come into it.
Absolutely no idea where to start! PSUEDOCODE might be:
CONCAT(
event_name = REPLACE( part of :search, ' ', '')
,
venue_name = REPLACE( part of :search, ' ', '')
)
= :search
If I used noddybobstheatre as the search term I want to search the column event_name for part of it and venue_name for another part and when the 2 parts are put together they equal the search term.
event_name = 'noddy'
venue_name = 'bobs theatre'
Like I said, this might be a crazy ask...
Reading what you need I thought that the like statement should use the column and not the search value.
here is my reproduction of what I understood from your problem
CREATE TABLE movies
(`word1` varchar(5), `word2` varchar(7))
;
INSERT INTO movies
(`word1`, `word2`)
VALUES
('micko', 'to'),
('he', 'llbrane'),
('mick', 'oto'),
('hell', 'brane')
;
then here is the sql statement that I used
select * from movies where 'mickoto' like CONCAT(Replace(word1,' ',''),'%') and 'mickoto' like CONCAT('%',Replace(word2,' ',''))
all you have is to adapt this to your context
here is the fiddle execution
use this,
concat(replace(event_name,' ',''),replace(venue_name,' ',''), )=:search

MYSQL - Use variable with Regex in select query to get records

There are strings in table
+1-123-456-7890
11234567890
+1 1234567890
1777555999
I have variable $phoneNumber. I want to pass variable in sql query to get matching records.
example:
$phoneNumber holds the value 1234567890
and using same variable I want to fetch following records in one query
+1-123-456-7890
11234567890
+1 1234567890
I want to select both records in one query.
how can I match data (11234567890) with above saved numbers?
We can do this following the replacement logic already suggested here combined with regular expressions, to match only the phone numbers with the format you want to target:
WITH yourTable AS (
SELECT '+1-123-456-7890' AS phone UNION ALL
SELECT '+1 1234567890' UNION ALL
SELECT '+6512345678'
)
SELECT
phone,
REPLACE(REPLACE(REPLACE(phone, ' ', ''), '+', ''), '-', '') AS common_phone
FROM yourTable
WHERE phone REGEXP '\\+[0-9][[:space:]-][0-9]{3}-?[0-9]{3}-?[0-9]{4}';
Demo
Try this !
Regex :
[\+]?[0-9](?:[-| ])?\d{3}[-]?\d{3}[-]?\d{4}
Verify through regxe101:
If both $phonenumber and your string column could (potentially) both have the troublesome characters, this is hard to solve with regular expressions.
where replace(replace(replace($phonenumber, ' ', ''), '-', ''), '+') = replace(replace(replace(phonecol, ' ', ''), '-', ''), '+')
I solved this with using replace() in query.
I removed special characters from variable $phoneNumber (not through sql but before passing varable to sql) and compared it with the string result of the replace. SELECT phone FROM myTable where REPLACE(REPLACE(REPLACE(phone, ' ', ''), '+', ''), '-', '') = $phoneNumber;
Rethink the overall design.
Cleanse phone numbers before putting them into the table. Then that SELECT, and the other SELECTs that are yet to be written, will be simple.

Need regex expression in mysql select query

I am writing the mysql query where I need to compare data entered by user with the sku column in database tab
Query is like
SELECT *
FROM `is_product_info`
WHERE REPLACE( '-', '', sku ) LIKE '%ETI2006%'
so that if sku in database contains "-" in sku, I am replacing all hyphens with "" before comparing.
so whether sju no contains ETI2006 or ETI-2006, it will come in output
I think you may just like this
SELECT * FROM is_product_info WHERE REPLACE( sku , '-', '' ) LIKE '%ETI2006%'
I didn't try on a running MySQL but this should work:
SELECT *
FROM `is_product_info`
WHERE sku REGEXP REPLACE('ETI-2006','-','-?');
I made the mistake in replace syntax, it works with the below one:
SELECT * FROM is_product_info WHERE REPLACE( sku , '-', '' ) LIKE '%ETI2006%'
Using replace() on every row is what's slowing it down.
All of these approaches should be faster - see which one works best for you:
Option 1 - use LIKE twice:
WHERE sku LIKE '%ETI-2006%'
OR sku LIKE '%ETI2006%'
Option 2 - Use RLIKE once:
WHERE sku RLIKE 'ETI-?2006'

Use replace with in clause

Got ids stored in DB with Json format like this
'["1454","474","545"]'
I can build list IDs :
SELECT replace
(replace(
replace(
replace('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\'')
mySql returns '1454','474','545'
But when I try to list DB records from this build list of IDs :
SELECT col FROM table WHERE col in (REPLACE
(REPLACE(
REPLACE(
REPLACE('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\''));
mySql says "0 records" even if I add a "SELECT" before the first "REPLACE"
Any help ?
Try below query, you need to add select in your in clause also:
SELECT col FROM table WHERE col in (select REPLACE
(REPLACE(
REPLACE(
REPLACE('["1454","474","545"]','[','\'')
,']','\'')
,'"','')
,',','\',\''));
Alas, you cannot use in with a comma delimited string. It takes a list of elements, but not within a string. So, this works as you expect:
where x in (1,2,3)
This does not work as you expect (although it does work as I expect0;
where x in ('1,2,3')
This looks for one value of x that is the string '1,2,3'.
The solution is to use the MySQL function find_in_set():
SELECT col
FROM table
WHERE find_in_set(col, REPLACE(REPLACE(REPLACE('["1454","474","545"]', '[','\''
), ']', '\''
), '"', ''
), ',', '\',\''
);
To be honest, though, you might be better off with something like:
where '["1454","474","545"]' like concat('%;', col, '&%')

Replace multiple things at once in MySQL?

Is it possible to replace multiple things at once in MySQL?
It feels kinda clumsy doing this
REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( REPLACE( myField, 'å', 'a' ) , 'Å', 'A' ) , 'Ø', 'O' ) , 'ø', 'o' ) , 'æ', 'a' ) , 'Æ', 'A' )
Short answer, no. There's really no need to elaborate :)
You can create your own user defined function to do this, but it's probably something I would put in a layer other than the database.
The database is optimised for the stuff it needs to do, data extraction/sorting/grouping and so on.
While it can do some manipulation of data within a column, that's not really its primary purpose (leave that to the presentation or other layers).
If you must do it within the DBMS, consider doing it with a separate column holding the modified data, and having that maintained with an insert/update trigger. This will at least ensure the cost is incurred only when the data changes, rather than every time you look at it. In other words, it will amortise the cost across all selects.