SQL Query that checks only numeric characters in the database - mysql

I am working on a legacy system a client has. Phone numbers are stored in a multitude of ways. Ex:
514-879-9989
514.989.2289
5147899287
The client wants to be able to search the database by phone number.
How could this be achieved without normalizing the data stored in the database? Is this possible?
I am wondering if it is possible to have a query that looks like:
SELECT FROM table WHERE phonenumber LIKE %input%
but that takes into account only the numerical characters in the db?

$sql = "SELECT * FROM tab
WHERE replace(replace(phone, '.', ''), '-', '') like '%". $input ."%'"
Yes you can add more replace according to values in your table, as mentioned by #spencer7593 eg:
$sql = "SELECT * FROM tab
WHERE replace(replace(replace(replace(replace(replace(phone, '.', ''), '-', ''), '+', ''), '(', ''), ')', ''), ' ', '') like '%". $input ."%'"
but I would prefer to cleanup the data before the query.

The approach I would take with this (i.e. not having a "normalized" value with only digits available, and a restriction of not adding an additional column with the normalized value...)
I would take the user input for the search, and add wild cards in strategic locations. For example, if the user provides search input of 3155551212), then I'd run a query that has a predicate equivalent to this:
phonenumber LIKE '%315%555%1212%'
But if I'm not guaranteed that the provided search digits will be a full three digit area code, a three digit exchange (central office) code, and a four digit line number, for a broader search, I'd add wild cards between all of the provided digits, e.g.
phonenumber LIKE '%3%1%5%5%5%5%1%2%1%2%'
This latter approach is less than ideal, because it could potentially provide more matches than aren't intended. Especially if the user is providing fewer than ten digits. For example, consider a phonenumber value:
'+1 (315) 555-7172 ext. 123'
As a demonstration:
SELECT '+1 (315) 555-7172 ext. 123' LIKE '%3%1%5%5%5%5%1%2%1%2%'
, '+1 (315) 555-7172 ext. 123' LIKE '%315%555%1212%'
There's no builtin string function in MySQL that will extract the digit characters from a string.
If you want a function that does that, e.g.
SELECT only_digits_from('+1 (315) 555-7172 ext. 123')
to return
13155557172123
You'd have to create a stored function that does that. I wouldn't attempt doing it inline in the SQL statement, that would require an atrociously long and ugly expression.

This is piece of code i frequently use to clean up the database columns. I have modified to to be fit for your purpose.
Update Table SET Column =
replace
(replace
(replace(column,
'-','',
'.',''),
' ','')
)
WHERE Column is Not Null

Related

How to adjust phone number to same format?

I want to extract data from my database, and I wish the when I extract the data all the h/p number all is same format.
sample:
+60161234567
016-1234567
0161234567
To:
+6016-1234567
The following simple code will give you the expected Output.
SELECT
(CASE
WHEN contact_number RLIKE "^[+]([0-9]){10}" THEN CONCAT(SUBSTRING(contact_number,1,5), "-", SUBSTRING(contact_number,6,7))
WHEN contact_number RLIKE "^([0-9]){3}[-]([0-9]){7}" THEN CONCAT("+6",contact_number)
WHEN contact_number RLIKE "^([0-9]){10}" THEN CONCAT("+6",SUBSTRING(contact_number,1,3), "-", SUBSTRING(contact_number,4,7))
ELSE 'Number is not in correct format'
END) AS 'Phone Number'
FROM table_name;
We have to use the regular expression for checking number format. I have done the query based on the number format that you have given. If a different format is there then try corresponding regular expression.
In the query, the 1st case for the number like "+60161234567", the 2nd case for the number like "016-1234567" and Last case for the number like "0161234567".
I have attached my SQLFiddle to this solution. You can check it. Thank you!
You can use concat and substr function to change format of phone number column during extracting data as below:
SELECT CONCAT(SUBSTR( contact_number, 1, 5 ) , "-", SUBSTR( contact_number, 5 ) ) AS phone_no FROM test_table;
Try this:
SELECT CONCAT("+6",SUBSTRING(REPLACE(REPLACE(phone, '+6', ''), '-', ''),1,3), "-", SUBSTRING(REPLACE(REPLACE(phone, '+6', ''), '-', ''),4,7)) FROM `phone`
It seems that an h/p number is a phone number?
This isn't a number, in the data type sense, so it shouldn't be stored as one. Numbers can have math applied to them and represent some finite value. Varchar or char is probably the appropriate data type here. When inserting the data, standardize the way you record the data and fix it in your application before inserting. In the US, phone numbers can be shown as (555) 123-4567 or 555-123-4567 so you could just pick the format — or what I would do is store it as 5551234567 and then format it in the application when displaying it to the user (that way, the user can prefer one format or the other). At the minimum, though, you should standardize the format when inserting the string so that you don't have to deal later with a variety of formats.
For data that already exists, I think your best bet is to fix the whole database. I would use some programming or scripting language that's good at manipulating data to fix it in the database (personally I think Python is a good choice).

Using COALESCE in MySQL

I'm just getting used to MySQL, I've come from a SQL Server background...
This SQL query builds an address how it should in SQL Server, how can I adapt it to use within MySQL. When I run it in SQL Server it displays all the data within each field, when run in MySQL it just shows me the first field.
Why would this be, what should I do different in MySQL?
SELECT COALESCE(House, '') + ' ' + COALESCE(StreetName, '') + ' ' + COALESCE(TownCity, '') + ' ' + COALESCE(Postcode, '') AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%'
Use the concat() function:
SELECT concat(COALESCE(House, ''), ' ', COALESCE(StreetName, ''), ' ',
COALESCE(TownCity, ''), ' ', COALESCE(Postcode, '')
) AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%';
You can also do this with concat_ws(). This eliminates the need for all the spaces:
SELECT concat_ws(COALESCE(House, ''), COALESCE(StreetName, ''),
COALESCE(TownCity, ''), COALESCE(Postcode, '')
) AS Display
FROM MyTable
WHERE Postcode LIKE '%A1 2AB%';
What happens in MySQL is that the + does just what you expect: it adds numbers. A string that contains a number is converted to a number automatically, with silent errors for strings that have no numbers. In practice, this means that a string that starts with a non-digit (and non-decimal point) is converted to a 0.
So, house, which presumably usually numeric, is converted to a number just fine. All the other strings are converted to numbers but become zero and the house number is not changed. You would have gotten much different results if your post codes were American-style zip codes (which are typically numeric).
EDIT:
As #fthiella points out, the coalesce() is not necessary for concat_ws(). The two statements would do different things, because NULLs in the original query result in repeated separators. NULLs in the concat_ws() version would have only a single separator (which might be desirable).
However, I would tend to keep the coalesce() anyway. The behavior of concat() and concat_ws() varies in this regard. concat() returns NULL if any of its arguments is NULL. concat_ws() skips NULL arguments after the initial separator. Who can remember that distinction? It sounds like a recipe for confusion in production code. So, I would also use coalesce() even though it is optional.

Cleaning out a field of Phone numbers in mySql

In not a database guy but: I have mixed up data in a mySql database that I inherited.
Some Phone numbers are formatted (512) 555-1212 (call it dirty)
Others 5125551212 (Call it clean)
I need a sqlstamet that says
UPDATE table_name
SET Phone="clean'(Some sort of cleaning code - regex?)
WHERE Phone='Dirty'
Unfortunately there's no regex replace/update in MySQL. If it's just parentheses and dashes and spaces then some nested REPLACE calls will do the trick:
UPDATE table_name
SET Phone = REPLACE(REPLACE(REPLACE(REPLACE(Phone, '-', ''), ')', ''), '(', ''), ' ', '')
To my knowledge you can't run a regexp to replace data during the update process. Only during the SELECT statement.
Your best bet is to use a scripting language that you're familiar with and read the table and change it that way. Basically by retrieving all the entries. Then using a string replace to match a simple regexp such as [^\d]* and remove those characters. Then update the table with the new value.
Also, see this answer:
How to do a regular expression replace in MySQL?

MySql : query to format a specific column in database table

I have one column name phone_number in the database table.Right now the numbers stored in the table are format like ex.+91-852-9689568.I want to format it and just want only digits.
How can i do it in MySql ? I have tried it with using functions like REGEXP but it displays error like function does not exist.And i don't want to use multiple REPLACE.
One of the options is to use mySql substring. (As long as the format doesn't change)
SELECT concat(SUBSTRING(pNo,2,2), SUBSTRING(pNo,5,3), SUBSTRING(pNo,9,7));
if you want to format via projection only, use SELECT, you will only need to use replace twice and no problem with that.
SELECT REPLACE(REPLACE(columnNAme, '-', ''), '+', '')
FROM tableName
otherwise, if you want to update the value permanently, use UPDATE
UPDATE tableName
SET columnName = REPLACE(REPLACE(columnNAme, '-', ''), '+', '')
MySQL does not have a builtin function for pattern-matching and replace.
You'll be better off fetching the whole string back to your application, and then using a more flexible string-manipulation function on it. For instance, preg_replace() in PHP.
Try the following and comment please.
Select dbo.Regex('\d+',pNo);
Select dbo.Regex('[0-9]+',pNo);
Reference on RUBLAR.
So MYSQL is not like Oracle, hence you may just use a USer defined Function to get numbers. This could get you going.

Format Phone Numbers in MySQL

I have a bunch of phone numbers in a DB that are formatted as such: (999) 123-3456.
I'm needing them to look like 123-123-1234
Is there any sort of regex or something I can do in MySQL to quickly format all these phone numbers?
Also, frustratingly, some are NOT formatted like that, so I couldn't just apply this to an entire column.
Thanks!
A quick solution would be to run these two queries:
UPDATE table_name set PhoneCol = REPLACE(PhoneCol, '(', '');
UPDATE table_name set PhoneCol = REPLACE(PhoneCol, ') ', '-');
Just write a small php script that loops through all the values and updates them. Making that change is pretty simple in php. Then just run an update on the row to overwrite the value.
maybe a two pass solution.
strip out all non-numeric characters (and spaces)
inset the formatting characters '(',')', ' ', and '-' into the correct spots
(or better yet, leave them off and format only during select on your reports.)
I had a similar problem, but increased by the reason that some phones had the format with the dashes and others did not and this was the command that helped me to update the formats of the numbers that did not have the hyphens.
Phone before the command: 1234567890
Phone after command: 123-456-7890
The phone field is called phone_number and is a VARCHAR
The command I used is:
UPDATE database.table
SET phone_number = concat(SUBSTRING(phone_number,1,3) , '-' , SUBSTRING(phone_number,4,3) , '-' , SUBSTRING(phone_number,7,4))
WHERE LOCATE('-', phone_number) = 0;
I think your command could be like this:
UPDATE database.table
SET phone_number = concat(SUBSTRING(phone_number,2,3) , '-' , SUBSTRING(phone_number,7,8));
I would remove the WHERE clause under the assumption that all phones would be formatted with the (). Also, the second string of characters would start from position 7 because there appears to be a space after the parentheses.