当前位置:  开发笔记 > 编程语言 > 正文

MySQL剥离非数字字符进行比较

如何解决《MySQL剥离非数字字符进行比较》经验,为你挑选了5个好方法。

我希望在表中找到与用户输入的特定号码匹配的记录.因此,用户可以输入12345,但这可能是数据库中的123zz4-5.

如果PHP函数在MySQL中运行,我想像这样的东西会起作用.

SELECT * FROM foo WHERE preg_replace("/[^0-9]/","",bar) = '12345'

只用MySQL做同样的功能或方法是什么?



1> 小智..:

我意识到这是一个古老的话题,但谷歌搜索这个问题我找不到一个简单的解决方案(我看到了古老的代理人,但认为这是一个更简单的解决方案)所以这是我写的一个函数,似乎工作得很好.

DROP FUNCTION IF EXISTS STRIP_NON_DIGIT;
DELIMITER $$
CREATE FUNCTION STRIP_NON_DIGIT(input VARCHAR(255))
   RETURNS VARCHAR(255)
BEGIN
   DECLARE output   VARCHAR(255) DEFAULT '';
   DECLARE iterator INT          DEFAULT 1;
   WHILE iterator < (LENGTH(input) + 1) DO
      IF SUBSTRING(input, iterator, 1) IN ( '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' ) THEN
         SET output = CONCAT(output, SUBSTRING(input, iterator, 1));
      END IF;
      SET iterator = iterator + 1;
   END WHILE;
   RETURN output;
END
$$



2> bobince..:

没有regexp替换,只有一个普通的字符串REPLACE().

MySQL有REGEXP运算符,但它只是一个匹配测试程序而不是一个替换程序,所以你必须从内到外打开逻辑:

SELECT * FROM foo WHERE bar REGEXP '[^0-9]*1[^0-9]*2[^0-9]*3[^0-9]*4[^0-9]*5[^0-9]*';

这就像你的LIKE版本,但更准确地匹配.两者都表现同样糟糕,需要没有索引的全表扫描.



3> wally..:

最受欢迎的答案(@ user1467716)并不是最快的.对他们给予工作建议反弹的全部赞誉!

这是一个改进版本:

DELIMITER ;;
DROP FUNCTION IF EXISTS `STRIP_NON_DIGIT`;;

CREATE DEFINER=`root`@`localhost` FUNCTION `STRIP_NON_DIGIT`(input VARCHAR(255)) RETURNS VARCHAR(255) CHARSET utf8
READS SQL DATA
BEGIN
   DECLARE output    VARCHAR(255) DEFAULT '';
   DECLARE iterator  INT          DEFAULT 1;
   DECLARE lastDigit INT          DEFAULT 1;
   DECLARE len       INT;

   SET len = LENGTH(input) + 1;
   WHILE iterator < len DO
      -- skip past all digits
      SET lastDigit = iterator;
      WHILE ORD(SUBSTRING(input, iterator, 1)) BETWEEN 48 AND 57 AND iterator < len DO
         SET iterator = iterator + 1;
      END WHILE;

      IF iterator != lastDigit THEN
         SET output = CONCAT(output, SUBSTRING(input, lastDigit, iterator - lastDigit));
      END IF;

      WHILE ORD(SUBSTRING(input, iterator, 1)) NOT BETWEEN 48 AND 57 AND iterator < len DO
         SET iterator = iterator + 1;
      END WHILE;
   END WHILE;

   RETURN output;
END;;

在测试服务器上测试5000次:

-- original
Execution Time : 7.389 sec
Execution Time : 7.257 sec
Execution Time : 7.506 sec

-- ORD between not string IN
Execution Time : 4.031 sec

-- With less substrings
Execution Time : 3.243 sec
Execution Time : 3.415 sec
Execution Time : 2.848 sec



4> Chris Bartow..:

虽然它不漂亮并且显示的结果不匹配,但这有助于:

SELECT * FROM foo WHERE bar LIKE = '%1%2%3%4%5%'

我仍然希望找到一个更好的解决方案,类似于原始问题中的项目.



5> Marlom..:

您可以轻松地完成所需的操作REGEXP_REPLACE(与MySQL 8+和MariaDB 10.0.5+兼容)

REGEXP_REPLACE(expr, pat, repl[, pos[, occurrence[, match_type]]])

用替换字符串repl替换字符串expr中与模式pat指定的正则表达式匹配的匹配项,并返回结果字符串。如果expr,pat或repl为NULL,则返回值为NULL。

转到REGEXP_REPLACE文档:MySQL或MariaDB

试试吧:

SELECT REGEXP_REPLACE('123asd12333', '[a-zA-Z]+', '');

输出:

12312333


模式“ [a-zA-Z] +”将仅删除字母,而不删除所有非数字字符。我认为[^ 0-9]会更好。SELECT REGEXP_REPLACE('áőüóöúeád123asd12333-%!','[^ 0-9]','');
推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有