如何使用SQL替换电话号码中的某些字符?
我有一个表如何使用SQL替换电话号码中的某些字符?,sql,regex,oracle,oracle11g,regexp-replace,Sql,Regex,Oracle,Oracle11g,Regexp Replace,我有一个表Contact,其中包含所有带有电话号码的用户联系人,需要对电话号码进行一些转换 我需要查看所有电话号码,并: 删除电话号码中出现的下列字符序列(0) 当缺少和插入电话号码时,添加前缀+ 示例: +-----+-----------+----------+---------+------------------------+ | id | firstname | lastname | country | phone | +-----+------
Contact
,其中包含所有带有电话号码的用户联系人,需要对电话号码进行一些转换
我需要查看所有电话号码,并:
(0)
+
+-----+-----------+----------+---------+------------------------+
| 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
+-----+-----------+----------+---------+------------------------+
+-----+--------------+--------+
| id | country_code | prefix |
+-----+--------------+--------+
| 100 | PL | 48 |
| 101 | US | 1 |
+-----+--------------+--------+
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
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 )
电话号码:+1(0)121
需要转换为:
+12121
电话号码:(0)121
需要转换为:
+12121
电话号码:121
需要转换为:
+12121
根据第1点:
我们可以通过查询选择所有电话号码:
select phone from contact where phone like '%(0)%';
但是如何仅从数字中删除该序列(0)
?如何为此创建更新查询
根据第2点:
如何识别电话号码是否不包含国家/地区直拨号码(前缀+
),如果缺少,如何添加正确的号码?
也许可以通过此查询选择这些数字:
select phone from contact where phone not like '%+%';
我们可以这样假设。我们还假设Contact table中有一列country,对于country Code List,我们可以基于此->创建临时映射表。我们可以简单地创建一个包含国家代码国家前缀映射的临时表,如下所示
我想应该可以调用更新查询,在第一步中,该查询将选择错误格式的所有电话号码,在第二步中,该查询将使用新的正确值进行更新,对吗?
我不太懂SQL,所以请帮我创建这样一个SQL查询
表格联系人:
+-----+-----------+----------+---------+------------------------+
| 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
+-----+-----------+----------+---------+------------------------+
+-----+--------------+--------+
| id | country_code | prefix |
+-----+--------------+--------+
| 100 | PL | 48 |
| 101 | US | 1 |
+-----+--------------+--------+
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
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 )
这应该不难。如果您的
联系人
表中有一个国家代码列,并且有一个单独的表国家/地区映射
,那么这样的查询可能如下所示(仅供参考,波兰的前缀是48
,正如您在联系人
表中正确显示的那样,而不是22
您在国家/地区映射
表中正确显示的那样):
对于更新
,我建议如下:
1。根据上面的查询创建一个临时表:
+-----+-----------+----------+---------+------------------------+
| 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
+-----+-----------+----------+---------+------------------------+
+-----+--------------+--------+
| id | country_code | prefix |
+-----+--------------+--------+
| 100 | PL | 48 |
| 101 | US | 1 |
+-----+--------------+--------+
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
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 )
2。从临时表更新:
+-----+-----------+----------+---------+------------------------+
| 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
+-----+-----------+----------+---------+------------------------+
+-----+--------------+--------+
| id | country_code | prefix |
+-----+--------------+--------+
| 100 | PL | 48 |
| 101 | US | 1 |
+-----+--------------+--------+
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
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。删除“临时”表,或者将其作为旧的、坏的电话号码的备份。
更新:如果在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 || ' \1') AS new_phone
FROM contact c, country_mapping cm
WHERE REGEXP_LIKE(c.phone, '(^[^+]|\(0\))')
AND c.country = cm.country_code
这也将删除电话号码中的前导空格。乍一看,我想说的是查看regexp\u replace没有一个简单的解决方案。例如,您可以在这里查看类似的问题(php+regexp)@TomášFejfar引用了通过正则表达式满足的标准要求,这相当具有挑战性,@Patrick,我不同意。这在支持POSIX正则表达式的Oracle中并不难做到。@David Faber是的,如果我们只清理带有
(0)
或缺少国家/地区直拨号码的电话号码,这是可行的(您的解决方案可以实现这一点)。如果我们想确保一个数字符合E.164标准,这是一个挑战(这里没有要求)。谢谢David,这是一个极好的解决方案!还有一个问题需要澄清另一种可能的情况:您的正则表达式条件应该如何更改以“+前缀”开头的电话号码-正如您在mark+
之前看到的,我们可以有一个空格,甚至两个空格?我会使用TRIM()
在应用正则表达式覆盖该情况之前,在c.phone
的值上。如果您必须担心其他空白字符,那么可以使用REGEXP\u REPLACE()
来完成此操作。如果您需要帮助,请告诉我,我会相应地更新我的答案。我对如何更新您的查询非常感兴趣,可以吗?我正在使用\s*
添加regex表达式中的某个地方,但到目前为止还没有成功。