[英]Sql correct filter for floats values in string column
我有表格发票,并且有“总计” varchar(255)列。 像这样的值:“ 500.00”,“ 5'199.00”,“ 129.60”,“ 1.00”等。 我需要选择记录并按总计列进行过滤。 例如,查找总计不超过180的记录。
我尝试了这个:
SELECT total from invoices WHERE invoices.total <= '180'
但结果是:
125.25
100.50
1593.55 - not correct
4'799.00 - not correct
1.00
-99.00
2406.52 -not correct
如何解决此问题并为此列编写正确的过滤器? 谢谢!
您可以使用cast()函数将其转换为float
SELECT total from invoices WHERE cast(invoices.total as decimal(16,2)) <= 180
为什么将数字存储为字符串? 那是您的数据模型的一个基本问题,应该修复它。
有时,我们会被别人的,非常非常错误的决定所束缚。 如果是这种情况,您可以尝试通过显式转换解决此问题:
SELECT i.total
FROM invoices i
WHERE CAST(REPLACE(i.total, '''', '') as DECIMAL(20, 4)) <= 180;
请注意,如果总计中还有其他意外字符,则将返回错误。
如果字符串以数字开头,然后包含非数字字符,则可以使用CAST()
函数或通过添加0
将其隐式转换为数字:
SELECT CAST('1234abc' AS UNSIGNED); -- 1234
SELECT '1234abc'+0; -- 1234
要从任意字符串中提取数字,您可以添加一个自定义函数,如下所示 :
DELIMITER $$
CREATE FUNCTION `ExtractNumber`(in_string VARCHAR(50))
RETURNS INT
NO SQL
BEGIN
DECLARE ctrNumber VARCHAR(50);
DECLARE finNumber VARCHAR(50) DEFAULT '';
DECLARE sChar VARCHAR(1);
DECLARE inti INTEGER DEFAULT 1;
IF LENGTH(in_string) > 0 THEN
WHILE(inti <= LENGTH(in_string)) DO
SET sChar = SUBSTRING(in_string, inti, 1);
SET ctrNumber = FIND_IN_SET(sChar, '0,1,2,3,4,5,6,7,8,9');
IF ctrNumber > 0 THEN
SET finNumber = CONCAT(finNumber, sChar);
END IF;
SET inti = inti + 1;
END WHILE;
RETURN CAST(finNumber AS UNSIGNED);
ELSE
RETURN 0;
END IF;
END$$
DELIMITER ;
定义函数后,您可以在查询中使用它:
SELECT total from invoices WHERE ExtractNumber(invoices.total) <= 180
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.