我理解比较花车的问题,并在这种情况下哀叹它们的使用 - 但我不是桌面作者,只有很小的障碍可以爬......
有人决定使用浮点数,因为您希望使用GUID。我需要检索具有特定浮点值的所有记录。
sp_help MyTable
-- Column_name Type Computed Length Prec
-- RandomGrouping float no 8 53
这是我天真的尝试:
--yields no results
SELECT RandomGrouping
FROM MyTable
WHERE RandomGrouping = 0.867153569942739
这是一个近似有效的尝试:
--yields 2 records
SELECT RandomGrouping
FROM MyTable
WHERE RandomGrouping BETWEEN 0.867153569942739 - 0.00000001
AND 0.867153569942739 + 0.00000001
-- 0.867153569942739
-- 0.867153569942739
在我天真的尝试中,这个文字是浮点文字吗?或者它是否真的是一个后来转换的十进制文字?
如果我的文字不是浮点文字,那么制作浮点文字的语法是什么?
编辑:我发生了另一种可能性......可能是这个列中存储的数字比显示的更精确。可能无法创建表示此数字的文字。我会接受证明情况就是这样的答案。
编辑:对DVK的回应。
TSQL是MSSQLServer的SQL方言。
此脚本有效,因此可以在浮点类型之间确定性地执行相等性:
DECLARE @X float
SELECT top 1 @X = RandomGrouping
FROM MyTable
WHERE RandomGrouping BETWEEN 0.839110948199148 - 0.000000000001
AND 0.839110948199148 + 0.000000000001
--yields two records
SELECT *
FROM MyTable
WHERE RandomGrouping = @X
我说“大约”因为该方法测试范围。使用该方法,我可以获得不等于我的预期值的值。
链接的文章不适用,因为我不是(故意)试图跨越小数和浮点数之间的世界边界。我正在努力只使用花车。这不是关于小数字到浮点数的不可转换性。
对Zinglon的回应:
可以找到我的记录的文字值,谢谢。
DECLARE @Y binary(8)
SET @Y = 0x3FEAD9FF34076378
SELECT *
FROM MyTable
WHERE convert(binary(8), RandomGrouping) = @Y
答案 0 :(得分:1)
有可能在显示时截断这些值。我假设列没有对它的唯一约束,否则问题将没有实际意义。在我的设置中,SSMS会截断此脚本中更精确的值。
create table flt ( f float not null primary key )
insert into flt
select 0.111111111111111
union all
select 0.1111111111111111
select f, cast(f as binary(8)) from flt
同样,如果这些值是不同的,您可以将它们转换为二进制(8)并根据该值识别它们,如下所示:
select f from flt
where cast(f as binary(8)) = 0x3FBC71C71C71C71C
答案 1 :(得分:0)
问题不在于它是否是浮点文字。
问题是在Sybase(或任何数据库服务器)中比较两个浮点数是否相等是不确定的,因为4.00000000000000000000 ...和3.99999999999999999999 ...是相同的确切数但不相等。
你的第二个解决方案是比较浮点数为“相等”的唯一正确方法(也就是说,它们是否与精度相同)。
为什么你对你的第二种方法说“近似工作”?
由于您没有提供您使用的特定数据库服务器,因此对于MySQL来说,这是一个相当不错的问题报告(与上面的结论基本相同)
http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html
答案 2 :(得分:0)
该文字是浮点文字吗?还是真的是小数 立即转换的文字?
如果我的文字不是浮点文字,则其语法是什么 制作浮点文字?
SQL Server中的0.867153569942739
文字是decimal
类型,而不是float
。
引擎会自动选择适当的比例和精度来表示给定的文字。
要编写float
类型的文字,您应该使用科学记号,如下所示:
0.867153569942739E0
十进制常数
十进制常量由以下字符串表示: 不包含在引号中且包含小数的数字 点。 以下是十进制常量的示例:
1894.1204 2.0
浮点数和实常数
float 和 real 常量由以下形式表示: 使用科学记数法。 以下是 float 或 real 值的示例:
101.5E5 0.5E-2
sp_describe_first_result_set
可以告诉我们列的类型
EXEC sp_describe_first_result_set N'SELECT 0.867153569942739, 0.867153569942739E0'
第一列返回numeric(15,15)
,第二列返回float
。
如果您对列RandomGrouping
进行了索引,则使用float
文字会更有效,因为当您将RandomGrouping
包装在convert()
中时,索引将无法被使用。
以下查询将使用索引:
SELECT *
FROM MyTable
WHERE RandomGrouping = 0.867153569942739E0
以下查询将不使用索引:
SELECT *
FROM MyTable
WHERE convert(binary(8), RandomGrouping) = @Y