繁体   English   中英

SQL正确的过滤器用于字符串列中的浮点值

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM