I have a table Contact
containing all user contacts with phone numbers and need to do some transformations for phone numbers.
I need to go through the all phone numbers and:
remove following characters sequence (0)
when present in the phone number;
add the prefix +<country_code>
when is missing and when a telephone number has been inserted;
Example:
The phone number:
+1 (0) 121 121 121
needs to be transformed to:
+1 121 121 121
The phone number:
(0) 121 121 121
needs to be transformed to:
+1 121 121 121
The phone number:
121 121 121
needs to be transformed to:
+1 121 121 121
We can select all phone numbers with query:
select phone from contact where phone like '%(0)%';
but how to remove that sequence (0)
only from the number? How to create an update query for that?
How to recognize if the phone number do not contain country direct number (prefix +<country_code>
) and add a correct one if is missing?
Maybe this query should be fine to select those numbers:
select phone from contact where phone not like '%+%';
We can assume that. Let's assume also that we have a column country in Contact table and for the Country Code List we can create temporary mapping table based on this -> http://countrycode.org/. We can simply create a temporary table containing country code <-> country prefix mapping as I showed below.
I guess that it should be possible to call an update query which in 1st step will select the all phone numbers in wrong format and in 2nd step will update with the new correct value, right? I do not know SQL very well, so please help me to create such a SQL query?
Table CONTACT:
+-----+-----------+----------+---------+------------------------+
| id | firstname | lastname | country | phone |
+-----+-----------+----------+---------+------------------------+
| 100 | Frank | Grob | PL | +48 22 121 121 121 | <- OK
| 101 | Bob | Bloby | PL | (0)22 121 121 121 | <- Wrong
| 102 | Alice | Wonder | US | +1 (0) 121 121 121 | <- Wrong
| 103 | Chris | Black | US | +1 (0) 121 121 121 | <- Wrong
| 104 | Rocky | Rocky | US | +1 (0) 121 121 121 | <- Wrong
+-----+-----------+----------+---------+------------------------+
Table COUNTRY_MAPPING:
+-----+--------------+--------+
| id | country_code | prefix |
+-----+--------------+--------+
| 100 | PL | 48 |
| 101 | US | 1 |
+-----+--------------+--------+
This should not be difficult. If you have a country code column in your CONTACT
table and a separate table COUNTRY_MAPPING
, then such a query might look like this (FYI, Poland's prefix is 48
as you correctly have in your CONTACT
table, not 22
as you have in your COUNTRY_MAPPING
table):
SELECT c.id, c.firstname, c.lastname, c.country, c.phone
, REGEXP_REPLACE(REGEXP_REPLACE(c.phone, '\(0\)\s*'), '^([^+])', '+' || cm.prefix || ' \1') AS new_phone
FROM contact c, country_mapping cm
WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))')
AND c.country = cm.country_code
Please see SQL Fiddle demo here.
For an UPDATE
I would recommend the following:
1. Create a temporary table based on the query above:
CREATE TABLE contact_newphone AS
SELECT c.id, c.firstname, c.lastname, c.country, c.phone
, REGEXP_REPLACE(REGEXP_REPLACE(c.phone, '\(0\)\s*'), '^([^+])', '+' || cm.prefix || ' \1') AS new_phone
FROM contact c, country_mapping cm
WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))')
AND c.country = cm.country_code
2. Update from that temporary table:
UPDATE contact c
SET c.phone = ( SELECT cn.newphone FROM contact_newphone cn
WHERE cn.id = c.id )
WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))') -- don't want to update anyone's phone# that might have been fixed!
AND EXISTS ( SELECT 1 FROM contact_newphone cn
WHERE cn.id = c.id )
3. Drop the "temporary" table - or keep it as a backup of the old, bad phone numbers.
UPDATE: If you have leading spaces in the phone
column, you might do the following in step 1
CREATE TABLE contact_newphone AS
SELECT c.id, c.firstname, c.lastname, c.country, c.phone
, REGEXP_REPLACE(REGEXP_REPLACE(REGEXP_REPLACE(c.phone, '^\s+'), '\(0\)\s*'), '^([^+])', '+' || cm.prefix || ' \1') AS new_phone
FROM contact c, country_mapping cm
WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))')
AND c.country = cm.country_code
Please see SQL Fiddle demo here. This will also remove leading spaces from phone numbers that are otherwise good.