如何在SQL Server中将浮点数转换为字符串

158

我有一个包含不同长度数字的浮点数列,我想将它们转换成varchar。

一些值超出了bigint的最大值,所以我不能像下面这样做:

cast(cast(float_field as bigint) as varchar(100))

我曾尝试使用 decimal,但数字大小不一,所以这也没有帮助

CONVERT(varchar(100), Cast(float_field as decimal(38, 0)))

非常感谢任何帮助。

更新:

示例的值为2.2000012095022E+26


float_field 强制转换为 varchar(max) - Denis Valeev
7
你的投入价值为2.2e+026。也许你没有理解问题的意思 :) - hgulyan
15个回答

298
尝试使用STR()函数。
SELECT STR(float_field, 25, 5)

STR() 函数


另外需要注意的是,此函数在左侧填充空格。如果这是一个问题,请与 LTRIM 结合使用:

SELECT LTRIM(STR(float_field, 25, 5))

5
我得到了*************************。那是什么? :) - hgulyan
4
“@hgulyan - Select LTRIM(Str(float_field, 38, 0)) 对于您的数据有效吗?” - Martin Smith
2
@hgulyan -最后十个数字为零是因为这是Str函数中的最后一个参数所指定的。它代表小数点后的数字位数。你有看我发的链接吗?把零改成10就可以了。 Select LTRIM(Str(float_field, 38, 10)) - codingbadger
4
我希望在SSMS中有一个警告:“嘿,当你将那个错误的浮点电话字段转换为文本时,请准备好用科学计数法得到一个漂亮的电话号码!我们不够聪明,不能先使用ltrim(str)”... - pkExec
它是一个浮点数,精度不到25位。对于小于1的数字,str(float_field,17,15)可以使用,而对于大于1的数字,则可以使用str(float_field,16,15)。(小于1的数字会添加一个计入总数的0) - blindguy
显示剩余2条评论

51

我发现唯一一个返回与原始数字完全相同的查询位是

CONVERT (VARCHAR(50), float_field,128)

请查看http://www.connectsql.com/2011/04/normal-0-microsoftinternetexplorer4.html

其他上述解决方案可能会对结果进行四舍五入或添加数字。

更新: 根据下面的评论和我在https://msdn.microsoft.com/en-us/library/ms187928.aspx中所看到的内容:

CONVERT (VARCHAR(50), float_field,3)

应该在新的SQL Server版本中使用(Azure SQL Database以及从SQL Server 2016 RC3开始)


3
+1 给 @adinas,浮点数值会按原样转换,但是 0 浮点数值会被转换为 0.0E0。我需要将浮点字段转换为 varchar,因为我需要在 NULL 时显示 NA,而在 0 时显示原值。我通过在查询中添加 CASE 语句来实现这一点,如下所示:CASE WHEN float_field IS NULL THEN 'NA' WHEN float_field = 0 THEN '0' ELSE CONVERT(VARCHAR, float_field, 128) END AS float_As_VChar - fujiFX
2
根据微软的文档 - https://msdn.microsoft.com/en-us/library/ms187928.aspx,128语法是出于遗留原因而包含的,可能会在未来版本中被弃用。 - Mike Turner
2
128已被弃用,但在最新的SQL Server版本中,3似乎是其替代品。 - user3524983
1
建议使用 CONVERT (VARCHAR(50), float_field,128) 并不准确,会引入舍入误差。而 CONVERT (VARCHAR(50), float_field,3) 则没有这个问题。 - CervEd

21

这是我最终在SQL Server 2012中使用的解决方案(因为所有其他建议均具有截断小数部分或其他缺点)。

declare @float float = 1000000000.1234;
select format(@float, N'#.##############################');

输出:

1000000000.1234

这进一步的优点(在我的情况下)是使千位分隔符和本地化变得更加容易:

select format(@float, N'#,##0.##########', 'de-DE');

输出:

1.000.000.000,1234

8
SELECT LTRIM(STR(float_field, 25, 0))

这是最好的方式,因此您不会在值的末尾添加.0000和任何数字。


6

首先转换为整型,然后再转换为字符串

cast((convert(int,b.tax_id)) as varchar(20))

2
这将删除小数点后的数字(如果有的话)。因此,这个解决方案不是很准确。 - RushabhG

3

感谢这个有用的主题。

如果你想像我一样去掉前导零,可以使用以下代码:

DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(LTRIM(REPLACE(STR(@MyFloat, 38, 16), '0', ' '))), ' ', '0'),'.',' ')),' ',',')

2

float 只有最大精度为15位数字。第15位之后的数字是随机的,转换成 bigint(最大19位)或 decimal 也无法解决此问题。


我不明白。字段值为2.2000012095022E+26。有什么解决办法吗?没有吗? - hgulyan
将值转换为字符串后,您无法获得比原始值中存储的数字更多的数字。 - devio
那么我在第15位之后丢失了数字? - hgulyan
数据出了一些问题,我只需要用一个15位小数来更新那个值。我会接受你的答案,因为它描述了我在处理这个数据时遇到的主要问题。谢谢。 - hgulyan

2

尝试这个,应该能行:

cast((convert(bigint,b.tax_id)) as varchar(20))

2

这可以在无需四舍五入的情况下帮助

declare @test float(25)

declare @test1 decimal(10,5)

select @test = 34.0387597207
select @test
set @test1 = convert (decimal(10,5), @test)
select cast((@test1) as varchar(12))


Select  LEFT(cast((@test1) as varchar(12)),LEN(cast((@test1) as varchar(12)))-1)

1

如果您使用CLR函数,您可以将浮点数转换为与浮点数完全相同但末尾没有多余0的字符串。

CLR函数

[Microsoft.SqlServer.Server.SqlFunction(DataAccess = DataAccessKind.Read)]
[return: SqlFacet(MaxSize = 50)]
public static SqlString float_to_str(double Value, int TruncAfter)
{
  string rtn1 = Value.ToString("R");
  string rtn2 = Value.ToString("0." + new string('0', TruncAfter));

  if (rtn1.Length < rtn2.Length) { return rtn1; } else { return rtn2; }
}

.

例子

create table #temp (value float)
insert into #temp values (0.73), (0), (0.63921), (-0.70945), (0.28), (0.72000002861023), (3.7), (-0.01), (0.86), (0.55489), (0.439999997615814)

select value,
       dbo.float_to_str(value, 18) as converted,
       case when value = cast(dbo.float_to_str(value, 18) as float) then 1 else 0 end as same
from   #temp

drop table #temp

.

输出

value                  converted                  same
---------------------- -------------------------- -----------
0.73                   0.73                       1
0                      0                          1
0.63921                0.63921                    1
-0.70945               -0.70945                   1
0.28                   0.28                       1
0.72000002861023       0.72000002861023           1
3.7                    3.7                        1
-0.01                  -0.01                      1
0.86                   0.86                       1
0.55489                0.55489                    1
0.439999997615814      0.439999997615814          1

.

注意事项

所有转换后的字符串都被截断到18个小数位,并且没有尾随的零。18位精度对我们来说不是问题。而且,我们近100,000个浮点数(约占全部FP数值的100%)作为字符串值和在数据库中的FP数值看起来完全一样。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接