如何从MySQL查询中的string提取数值?

我有一个两列的表:price(int)和price_display(varchar)。

价格是实际的数字价格,例如“9990”

price_display是可视化表示,例如“$ 9.99”或“9.99Fr”

我已经能够确认通过正则expression式匹配的两列:

price_display不是正则expression式格式(price / 1000,2)

但是在不匹配的情况下,我想从price_display列中提取值并将其设置到price列中,所有这些都在更新语句的上下文中。 我一直无法弄清楚如何。

谢谢。

这个函数完成的工作只是从string中返回数字0-9,这样可以很好地解决你的问题,而不pipe你有什么前缀或后缀。

http://www.artfulsoftware.com/infotree/queries.php?&bw=1280#815

复制在这里以供参考:

SET GLOBAL log_bin_trust_function_creators=1; DROP FUNCTION IF EXISTS digits; DELIMITER | CREATE FUNCTION digits( str CHAR(32) ) RETURNS CHAR(32) BEGIN DECLARE i, len SMALLINT DEFAULT 1; DECLARE ret CHAR(32) DEFAULT ''; DECLARE c CHAR(1); IF str IS NULL THEN RETURN ""; END IF; SET len = CHAR_LENGTH( str ); REPEAT BEGIN SET c = MID( str, i, 1 ); IF c BETWEEN '0' AND '9' THEN SET ret=CONCAT(ret,c); END IF; SET i = i + 1; END; UNTIL i > len END REPEAT; RETURN ret; END | DELIMITER ; SELECT digits('$10.00Fr'); #returns 1000 

一种方法是使用REPLACE()函数:

 UPDATE my_table SET price = replace(replace(replace(price_display,'Fr',''),'$',''),'.','') WHERE price_display not regexp format(price/1000, 2); 

这适用于您提供的示例数据:

 '$9.99' '9.99Fr' 

两者都在我的testing结果999。 有了这样的更新,务必首先备份数据库,并了解项目的格式。 您可以通过执行此查询来查看所有“baddies”:

 SELECT DISTINCT price_display FROM my_table WHERE price_display not regexp format(price/1000, 2) ORDER BY price_display; 

对我来说,CASTING领域做了诀窍:

CAST( price AS UNSIGNED ) //对于正整数

CAST( price AS SIGNED ) //用于负数和正整数

IF(CAST(price AS UNSIGNED)=0,REVERSE(CAST(REVERSE(price) AS UNSIGNED)),CAST(price AS UNSIGNED)) //当价格开始时,

有关更多详情,请参阅

https://dev.mysql.com/doc/refman/5.0/en/cast-functions.html

我创build一个程序,检测string中的第一个数字,并返回这个,如果不返回0。

  DROP FUNCTION IF EXISTS extractNumber; DELIMITER // CREATE FUNCTION extractNumber (string1 VARCHAR(255)) RETURNS INT(11) BEGIN DECLARE position, result, longitude INT(11) DEFAULT 0; DECLARE string2 VARCHAR(255); SET longitude = LENGTH(string1); SET result = CONVERT(string1, SIGNED); IF result = 0 THEN IF string1 REGEXP('[0-9]') THEN SET position = 2; checkString:WHILE position <= longitude DO SET string2 = SUBSTR(string1 FROM position); IF CONVERT(string2, SIGNED) != 0 THEN SET result = CONVERT(string2, SIGNED); LEAVE checkString; END IF; SET position = position + 1; END WHILE; END IF; END IF; RETURN result; END // DELIMITER ; 

返回string中的最后一个数字:

 CREATE FUNCTION getLastNumber(str VARCHAR(255)) RETURNS INT(11) DELIMETER // BEGIN DECLARE last_number, str_length, position INT(11) DEFAULT 0; DECLARE temp_char VARCHAR(1); DECLARE temp_char_before VARCHAR(1); IF str IS NULL THEN RETURN -1; END IF; SET str_length = LENGTH(str); WHILE position <= str_length DO SET temp_char = MID(str, position, 1); IF position > 0 THEN SET temp_char_before = MID(str, position - 1, 1); END IF; IF temp_char BETWEEN '0' AND '9' THEN SET last_number = last_number * 10 + temp_char; END IF; IF (temp_char_before NOT BETWEEN '0' AND '9') AND (temp_char BETWEEN '0' AND '9') THEN SET last_number = temp_char; END IF; SET position = position + 1; END WHILE; RETURN last_number; END// DELIMETER; 

然后调用这个函数:

selectgetLastNumber(“ssss111www222w”); 打印222

selectgetLastNumber(“ssss111www222www3332”); 打印3332

这是一个“编码恐怖”,关系数据库模式不应该这样写!

你必须编写复杂和不必要的代码来validation数据。

尝试这样的事情:

 SELECT CONCAT('$',(price/1000)) AS Price FROM ... 

另外,你可以使用floatdoublereal而不是整数。

如果您需要存储货币数据,则可以考虑添加货币字段或使用系统区域设置function以正确的格式显示它。