TSQL - 创建一个文字浮点值

时间:2010-06-11 16:01:10

标签: sql sql-server tsql floating-point literals

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

有人决定使用浮点数,因为您希望使用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

3 个答案:

答案 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

这已记录在Constants (Transact-SQL)

  

十进制常数

     

十进制常量由以下字符串表示:   不包含在引号中且包含小数的数字   点。   以下是十进制常量的示例:

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