从字段中删除所有非数字字符

Remove all non-numeric characters from a field

我有一个来自网络表单的结果集,其中每个集都有一个 phone 编号。此 phone 号码的格式未强制执行(有些是 xxxxxxxxxx,有些是 (xxx)xxx-xxxx,有些是 xxx-xxx-xxxx)。这是短视的,现在我需要能够根据 phone 数字(Views exposed filter)获得结果。

我解决此问题的最佳方法是使用 sql 查询重新格式化此字段中的值,以便去除所有非数字值。我已经尝试了几个我在类似问题上发现的函数,并且 none 似乎正在工作(我正在使用 mysql workbench 并收到 "function does not exist" 错误).这是我曾经做过的事情,我正在寻找一个我可以 运行 的查询,它将去除所有非数字值。我只需要 运行 它一次,因为我从这里开始验证 phone 数字只是数字。

是否有 sql 查询可以满足我的需要?使用 PHP 它只是

update table set data = preg_replace("/[^0-9]/", "", data) where condition

但我似乎找不到使用 SQL 执行此操作的方法。

这可能有用,但有点乏味:

从 table

中获取号码列表
$result = mysql_query("Select ID, number from Table"); 

每个值

while ($row = mysql_fetch_array($result)) { 
$ID = $row["ID"]; 
$NUM = $row["number"]; 

然后执行正则表达式模式并将该值更新为 ID

$NUM = eregi_replace("whateverregex","",$NUM); 

$sql = mysql_query("Update Table set number = $NUM where ID = $ID"); 
} 

在 MySQL 中没有任何 "builtin" 函数可以执行此操作。

一种选择是创建您自己的存储函数(如果您对数据库有足够的权限)。

 DELIMITER $$

 DROP FUNCTION IF EXISTS `uf_only_digits`$$

 CREATE FUNCTION `uf_only_digits`(as_val VARCHAR(65535))
 RETURNS VARCHAR(65535)
 DETERMINISTIC
 BEGIN
   DECLARE retval VARCHAR(65535);
   DECLARE i INT;
   DECLARE strlen INT;
   -- shortcut exit for special cases
   IF as_val IS NULL OR as_val = '' THEN
     RETURN as_val;
   END IF;
   -- initialize for loop
   SET retval = '';
   SET i = 1;
   SET strlen = CHAR_LENGTH(as_val);
 do_loop:
   LOOP
     IF i > strlen THEN
       LEAVE do_loop;
     END IF;
     IF SUBSTR(as_val,i,1) IN ('0','1','2','3','4','5','6','7','8','9') THEN
       SET retval = CONCAT(retval,SUBSTR(as_val,i,1));
     END IF;
     SET i = i + 1;
   END LOOP do_loop;
   RETURN retval;
 END$$

 DELIMITER ;

并且在使用 UPDATE 语句之前一定要测试

 SELECT t.foo
      , uf_only_digits(t.foo)
   FROM ( SELECT '' AS foo
          UNION ALL SELECT ' x'
          UNION ALL SELECT 'a1b2'
          UNION ALL SELECT '1-888-555-1212 ext 213'
          UNION ALL SELECT '1-800-FLOWERS'
        ) t

Returns:

 foo                     uf_only_digits(t.foo)  newlen  
 ----------------------  ---------------------  --------
                                                       0
  x                                                    0
 a1b2                    12                            2
 1-888-555-1212 ext 213  18885551212213               14
 1-800-FLOWERS           1800                          4

(最后两行可能会让我们停下来重新考虑我们真正想要实现的目标。如果是我,我会在执行更新之前创建一个新列,并在其中保存现有值。)

 -- new column same size as `phone` column
 ALTER TABLE mytable ADD COLUMN orig_phone VARCHAR(40) NULL 
   COMMENT 'original phone value, before update to all digits';

 UPDATE mytable t
    SET t.orig_phone = t.phone ;

 UPDATE mytable t
    SET t.phone = uf_only_digits(t.phone) ;

不漂亮,但是...

UPDATE table
SET data =
 CONCAT(
    IF (SUBSTRING(data, 01, 1) REGEXP '[0-9]', SUBSTRING(data, 01, 1), '')
,   IF (SUBSTRING(data, 02, 1) REGEXP '[0-9]', SUBSTRING(data, 02, 1), '')
,   IF (SUBSTRING(data, 03, 1) REGEXP '[0-9]', SUBSTRING(data, 03, 1), '')
,   IF (SUBSTRING(data, 04, 1) REGEXP '[0-9]', SUBSTRING(data, 04, 1), '')
,   IF (SUBSTRING(data, 05, 1) REGEXP '[0-9]', SUBSTRING(data, 05, 1), '')
,   IF (SUBSTRING(data, 06, 1) REGEXP '[0-9]', SUBSTRING(data, 06, 1), '')
,   IF (SUBSTRING(data, 07, 1) REGEXP '[0-9]', SUBSTRING(data, 07, 1), '')
,   IF (SUBSTRING(data, 08, 1) REGEXP '[0-9]', SUBSTRING(data, 08, 1), '')
,   IF (SUBSTRING(data, 09, 1) REGEXP '[0-9]', SUBSTRING(data, 09, 1), '')
,   IF (SUBSTRING(data, 10, 1) REGEXP '[0-9]', SUBSTRING(data, 10, 1), '')
,   IF (SUBSTRING(data, 11, 1) REGEXP '[0-9]', SUBSTRING(data, 11, 1), '')
,   IF (SUBSTRING(data, 12, 1) REGEXP '[0-9]', SUBSTRING(data, 12, 1), '')
,   IF (SUBSTRING(data, 13, 1) REGEXP '[0-9]', SUBSTRING(data, 13, 1), '')
,   IF (SUBSTRING(data, 14, 1) REGEXP '[0-9]', SUBSTRING(data, 14, 1), '')
,   IF (SUBSTRING(data, 15, 1) REGEXP '[0-9]', SUBSTRING(data, 15, 1), '')
,   IF (SUBSTRING(data, 16, 1) REGEXP '[0-9]', SUBSTRING(data, 16, 1), '')
)
WHERE condition

您可能需要多次复制连接的 IF 函数,具体取决于字段的长度和输入的格式。

SQLFiddle

查看正在运行的查询

在 MySQL 8.0+ 上有一个名为 REGEXP_REPLACE 的新本机函数。这个问题的一个干净的解决方案是:

update table set data = REGEXP_REPLACE(data, '[^0-9]+', "") where condition