对浮点字段的SQL服务器'like'会产生不一致的结果

时间:2013-06-12 15:49:27

标签: sql sql-server tsql

我正在使用LIKE向float字段返回匹配的数字结果。似乎一旦小数点左边有超过4位数字,就不会返回与小数点右侧的搜索项匹配的值。这是一个说明情况的例子:

CREATE TABLE number_like_test (
  num [FLOAT] NULL
)

INSERT INTO number_like_test (num) VALUES (1234.56)
INSERT INTO number_like_test (num) VALUES (3457.68)
INSERT INTO number_like_test (num) VALUES (13457.68)
INSERT INTO number_like_test (num) VALUES (1234.76)
INSERT INTO number_like_test (num) VALUES (23456.78)

SELECT num FROM number_like_test
WHERE num LIKE '%68%'

该查询不返回值为12357.68的记录,但它确实返回值为3457.68的记录。同样使用78而不是68运行查询不会返回23456.78记录,但使用76将返回1234.76记录。

所以要回答这个问题:为什么拥有更大的数字会导致这些结果发生变化?如何更改查询以获得预期结果?

5 个答案:

答案 0 :(得分:5)

like运算符需要一个字符串作为左侧值。根据文档,从floatvarchar的转换可以使用several styles

Value         Output
0 (default)   A maximum of 6 digits. Use in scientific notation, when appropriate.
1             Always 8 digits. Always use in scientific notation.
2             Always 16 digits. Always use in scientific notation.

默认样式适用于3457.68中的六位数字,但不适用于13457.68中的七位数字。要使用16位而不是6位,可以使用convert并指定样式2.样式2表示类似3.457680000000000e+003的数字。但这不适用于前两位数字,并且您可以免费获得意外的+003指数。

最佳方法可能是从float转换为decimal。该转换允许您指定比例和精度。使用scale 20和precision 10,float表示为3457.6800000000

where   convert(decimal(20,10), num) like '%68%'

答案 1 :(得分:2)

当您将数字与LIKE进行比较时,它会被隐式转换为字符串然后匹配
这里的问题是浮点数不精确,当它被转换时你可以得到
13457.679999999999999而不是13457.68

所以要以适当的格式显示这个明确的格式编号(不确定如何在sql server中执行此操作,但它会是这样的)

SELECT num FROM number_like_test
WHERE Format("0.##",num) LIKE '%68%'

答案 2 :(得分:2)

转换为字符串会使您的值四舍五入。 CONVERTCAST都有相同的行为。

SELECT cast(num as nvarchar(50)) as s
FROM number_like_test

SELECT convert(nvarchar(50), num) as s
FROM number_like_test

提供结果:

1234.56
3457.68
13457.7
1234.76
23456.8

您必须使用STR函数和正确的格式参数来尝试获取结果。例如,

SELECT STR(num, 10, 2) as s
FROM number_like_test

给出:

   1234.56
   3457.68
  13457.68
   1234.76
  23456.78

答案 3 :(得分:2)

已经很好地解决了,但你只需要一次CAST,而不是像其他答案所说的那样两次,LIKE负责字符串转换:

SELECT *
FROM number_like_test
WHERE CAST(num AS DECIMAL(12,6)) LIKE '%68%'

这是一个显示舍入行为的SQL小提琴:SQL Fiddle

答案 4 :(得分:1)

这可能是因为FLOAT数据类型表示floating point number,它是数字的近似值,不应依赖于精确比较。

如果你需要进行包含浮点值的搜索,你需要将它存储在十进制数据类型中(它将保存确切的数字)或使用类似the STR() function <的方式将其转换为varchar / p>