如何使用 SQL 替换 phone 数字中的某些字符?

How to replace some characters in phone number using SQL?

我有一个 table Contact 包含所有具有 phone 号码的用户联系人,需要对 phone 号码进行一些转换。

我需要检查所有 phone 个号码,并且:

  1. 删除 (0) 之后出现在 phone 号码中的字符序列;

  2. 添加前缀+<country_code>,当缺少和插入电话phone号码时;

示例:

phone号:
+1 (0) 121 121 121
需要转换为:
+1 121 121 121

phone号:
(0) 121 121 121
需要转换为:
+1 121 121 121

phone号:
121 121 121
需要转换为:
+1 121 121 121

根据第1点:

我们可以 select 所有 phone 号码查询:

select phone from contact where phone like '%(0)%';

但是如何仅从数字中删除该序列 (0)?如何为此创建更新查询?

根据第2点:

如何识别phone号码是否包含国家直拨号码(前缀+<country_code>)并在缺少时添加正确号码? 也许这个查询应该可以 select 这些数字:

select phone from contact where phone not like '%+%';

我们可以假设。我们还假设我们在联系人 table 中有一个国家/地区列,对于国家/地区代码列表,我们可以基于此创建临时映射 table -> http://countrycode.org/。我们可以简单地创建一个包含国家代码 <-> 国家前缀映射的临时 table,如下所示。

我想应该可以调用更新查询,在第一步中将 select 所有 phone 格式错误的数字,在第二步中将更新为新的正确值,正确的? 我不太了解 SQL,所以请帮我创建这样一个 SQL 查询?

Table 联系方式:

+-----+-----------+----------+---------+------------------------+
| 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      |
+-----+--------------+--------+

这应该不难。如果您的 CONTACT table 中有一个国家代码列和一个单独的 table COUNTRY_MAPPING,那么这样的查询可能看起来像这样(仅供参考,波兰的前缀是 48 正如你在 CONTACT table 中正确拥有的那样,而不是像你在 COUNTRY_MAPPING table 中拥有的 22:

SELECT c.id, c.firstname, c.lastname, c.country, c.phone
     , REGEXP_REPLACE(REGEXP_REPLACE(c.phone, '\(0\)\s*'), '^([^+])', '+' || cm.prefix || ' ') 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.

对于 UPDATE 我会推荐以下内容:

1.根据上面的查询创建临时 table:

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 || ' ') AS new_phone
  FROM contact c, country_mapping cm
 WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))')
   AND c.country = cm.country_code

2。从临时更新 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。删除 "temporary" table - 或者保留它作为旧的、坏的 phone 号码的备份。

更新:如果 phone 列中有前导空格,您可以在步骤 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 || ' ') 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. 这也将从 phone 数字中删除前导空格,否则这些空格是好的。