2013-06-12 84 views
2

我使用LIKE来针对float字段返回匹配的数字结果。似乎一旦小数点左边的位数超过4位,就不会返回与小数点右边的搜索项匹配的值。下面是说明这种情况的例子:针对float字段的SQL服务器“like”产生不一致的结果

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记录。

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

+6

**不要对数字使用'LIKE' **这是用于字符串字符串比较。 – JNK

+0

@JNK,如果数值被转换为字符串呢? – rosscj2533

+1

你可以这样做我猜,但为什么你在地球上? – JNK

回答

4

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指数。

最好的方法可能是从floatdecimal的转换。该转换允许您指定比例和精度。使用台秤20和精度10,浮子被表示为3457.6800000000

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

好的答案,即使它与小数转换一起工作,这填补了为什么它不起作用的问题,由于数字的数量。外部转换为varchar真的需要吗? – rosscj2533

+0

好点,它看起来像外部转换不是必需的。从“decimal”到“varchar”的隐式转换不会丢失数字。 – Andomar

1

这可能是因为一个FLOAT数据类型代表一个floating point number这是一个近似的数字,不应该依靠精确的比较。

如果你需要做的,包括你需要要么将其存储在十进制数据类型(这将持有的确切数字),或使用类似the STR() function

2

其转换为varchar浮动值的搜索当你与LIKE比较数字是隐式转换为字符串,然后匹配
这里的问题是,浮点数不准确的,当它被转换,你可以得到
13457.679999999999999代替13457.68

所以要狂热这明确地f在适当的格式ORMAT数(不知道如何做到这一点在SQL Server中,但它会是这样的),以字符串转换舍入你的价值观

SELECT num FROM number_like_test 
WHERE Format("0.##",num) LIKE '%68%' 
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 
+0

但是在where子句中使用类似的值(强制转换或转换)仍然会给出错误的结果。由于float数据类型的精确性,我需要将其转换为十进制(如NenadZivkovic注释)。 – rosscj2533

+0

您的编辑在where子句中正常工作。谢谢。 – rosscj2533

+0

@ rosscj2533 - 是的,这就是我想说的。将其转换为十进制可能是正确的选择,但也可以使用带有正确格式参数的STR。 – ken

2

漂亮很好的解决了,但你只需要像其他答案建议投一次,而不是两次,像取字符串转换的护理:

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

这里是一个SQL捣鼓出的舍入行为:SQL Fiddle