TSQL - 创建一个文字浮点值

问题描述 投票:4回答:3

我理解比较花车的问题,并在这种情况下对它们的使用感到遗憾 - 但我不是桌面作者,只有很小的障碍可以爬......

有人决定使用浮点数,因为你期望使用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方言。

此脚本有效,因此可以在float类型之间确定性地执行相等性:

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
sql sql-server tsql floating-point literals
3个回答
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
投票

这个文字是一个浮点文字吗?或者它是否真的是一个后来转换的十进制文字?

如果我的文字不是浮点文字,那么制作浮点文字的语法是什么?

SQL Server中的0.867153569942739文字是decimal类型,而不是float。引擎自动选择适当的比例和精度来表示给定的文字。

要写一个float类型的文字,你应该使用科学记数法,如下所示:0.867153569942739E0

这在Constants (Transact-SQL)中有记载

十进制常数

十进制常量由一串数字表示,这些数字未用引号括起来并包含小数点。以下是十进制常量的示例:

1894.1204  
2.0  

浮点数和实常数

浮点数和实常数用科学记数法表示。以下是浮点值或实数值的示例:

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

0
投票

问题不在于它是否是浮点字面量。

问题是在Sybase(或任何数据库服务器)中比较两个浮点的相等性是不确定的,因为4.00000000000000000000 ...和3.99999999999999999999 ...是相同的确切数但不相等。

你的第二个解决方案是唯一正确的方法来比较浮点数的“相等性”(也就是说,它们是否与精度相同)。

你为什么要对你的第二种方法说“近似工作”?

既然你没有提供你使用的特定数据库服务器,这里有一个相当不错的问题报告(与上面的结论基本相同)对于MySQL

http://dev.mysql.com/doc/refman/5.0/en/problems-with-float.html

© www.soinside.com 2019 - 2024. All rights reserved.