2010-08-26 28 views
2

比方说,我有一个数据库表中decimal (18,9)标识列下列数据:根据与小数点右侧相匹配的值过滤数据的好方法是什么?

ID 
======== 
1000.00 
1001.23 
1002.00 
1003.23 

我想写只会返回.230000000为小数点右边那些记录的SQL查询,这样,只有下面的返回:

1001.23 
1003.23 

我知道我可以将其转换为字符串做一个字符串比较做到这一点,但有不涉及字符串比较,是更有效的一种更好的方式在处理数字值?


基于Martin's answer,我想用最好的解决办法是,像这样:

Abs(ID - Cast(ID As int)) 

我加入了Abs()功能与负数的工作。

我跑了下面的测试,以确保我没有得到奇怪的舍入误差:

Declare @ID decimal(18,9) 

Set @ID = 1000.000000000 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: 1000.000000000 0.000000000 

Set @ID = -1000.000000000 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: -1000.000000000 0.000000000 

Set @ID = 1000.000000001 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: 1000.000000001 0.000000001 

Set @ID = -1000.000000001 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: -1000.000000001 0.000000001 

Set @ID = 1000.999999999 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: 1000.999999999 0.999999999 

Set @ID = -1000.999999999 
Select @ID, Abs(@ID - Cast(@ID As int)) 
-- Returns: -1000.999999999 0.999999999 

回答

2

你可以创建一个持久化计算列

id - cast(id as int) 

所以,你可以再索引它?

+0

感谢您的建议。你喜欢'cast'作为'int'还是'Round'?投掷时我总是被隐含的四舍五入所吓倒。另外,对计算列有很好的建议,但我无法将列添加到此表中。 – 2010-08-26 18:24:00

+0

@Ben - 我把它当作'int',因为我不确定你是否会处理小于0.5的十进制值,然后会被舍入而不是下降。例如,选择3.7 - ROUND(3.7,0)给出了'-0.3'。 – 2010-08-26 18:26:12

+0

好的。我想我主要关心的是我需要能够相信'cast'作为'int'总是通过简单地删除小数值来返回数字的整数部分。 – 2010-08-26 18:27:55

2
SELECT 
    [ID] 
FROM 
    [TABLE] 
WHERE 
    [ID] - ROUND([ID], 0) = .23 
+0

感谢您的想法。你是否有理由使用“Round”与其他方法?我被其他语言/平台上的'Round'烧毁,其行为与我预期的完全不同。 – 2010-08-26 18:24:49

+0

在过去,我使用了演员表,但是在回答时我完全放弃了自己的想法;) – 2010-08-26 18:51:22

0

这个怎么样?

SELECT MyCol 
FROM MyTable 
WHERE MyCol - ROUND(MyCol, 0) = .23 
相关问题