Amy*_*y B 5 sql t-sql sql-server floating-point literals
我了解比较浮点数的许多问题,并在这种情况下对它们的使用感到遗憾-但我不是表格的作者,攀爬的障碍很小。
有人决定使用浮点数,因为您希望使用GUID。我需要检索具有特定浮点值的所有记录。
sp_help MyTable
-- Column_name Type Computed Length Prec
-- RandomGrouping float no 8 53
Run Code Online (Sandbox Code Playgroud)
这是我天真的尝试:
--yields no results
SELECT RandomGrouping
FROM MyTable
WHERE RandomGrouping = 0.867153569942739
Run Code Online (Sandbox Code Playgroud)
这是一个大概的工作尝试:
--yields 2 records
SELECT RandomGrouping
FROM MyTable
WHERE RandomGrouping BETWEEN 0.867153569942739 - 0.00000001
AND 0.867153569942739 + 0.00000001
-- 0.867153569942739
-- 0.867153569942739
Run Code Online (Sandbox Code Playgroud)
在我幼稚的尝试中,该文字是浮点文字吗?还是真的是十进制文字,以后会转换?
如果我的文字不是浮点文字,那么制作浮点文字的语法是什么?
编辑:我发生了另一种可能性...它可能是比显示的更精确的数字存储在此列中。创建表示该数字的文字可能是不可能的。我将接受证明确实如此的答案。
编辑:对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
Run Code Online (Sandbox Code Playgroud)
我说“大约”是因为该方法会测试一个范围。使用这种方法,我可以获得的值不等于我的预期值。
链接的文章不适用,因为我没有(有意地)尝试跨越小数和浮点数之间的世界边界。我正在尝试仅使用浮点数。这与小数到浮点数的不可转换有关。
回应Zinglon:
可以找到我的记录的文字值,谢谢。
DECLARE @Y binary(8)
SET @Y = 0x3FEAD9FF34076378
SELECT *
FROM MyTable
WHERE convert(binary(8), RandomGrouping) = @Y
Run Code Online (Sandbox Code Playgroud)
该文字是浮点文字吗?或者它真的是一个稍后转换的十进制文字?
如果我的文字不是浮点文字,那么制作浮点文字的语法是什么?
0.867153569942739
SQL Server 中的文字是一种decimal
类型,而不是float
. 引擎会自动选择适当的比例和精度来表示给定的文字。
要编写该float
类型的文字,您应该使用科学记数法,如下所示:
0.867153569942739E0
十进制常数
十进制常量由一串没有用引号括起来并包含小数点的数字表示。以下是十进制常量的示例:
Run Code Online (Sandbox Code Playgroud)1894.1204 2.0
浮点数和实数常数
浮点数和实数常数用科学记数法表示。以下是浮点值或实值的示例:
Run Code Online (Sandbox Code Playgroud)101.5E5 0.5E-2
该sp_describe_first_result_set
可以告诉我们类型的列
EXEC sp_describe_first_result_set N'SELECT 0.867153569942739, 0.867153569942739E0'
Run Code Online (Sandbox Code Playgroud)
它返回numeric(15,15)
第一列和float
第二列。
如果列RandomGrouping
的索引,它是更有效使用float
文字,因为当你包裹RandomGrouping
中convert()
,不能使用索引。
以下查询将使用索引:
SELECT *
FROM MyTable
WHERE RandomGrouping = 0.867153569942739E0
Run Code Online (Sandbox Code Playgroud)
以下查询不会使用索引:
SELECT *
FROM MyTable
WHERE convert(binary(8), RandomGrouping) = @Y
Run Code Online (Sandbox Code Playgroud)
显示的值可能被截断。我假设该列没有唯一的约束,否则问题将毫无意义。在我的设置中,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
Run Code Online (Sandbox Code Playgroud)
同样,如果这些值不同,您可以将它们转换为二进制(8)并根据该值识别它们,如下所示:
select f from flt
where cast(f as binary(8)) = 0x3FBC71C71C71C71C
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3822 次 |
最近记录: |