如何在 SQLServer 中将 float 转换为 varchar

我有一个不同长度的浮点数列我试着把它们转换成 varchar。

有些值超过 bigint max size,所以我不能这样做

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

我试过用十进制,但数字的大小不一样,所以这也没有帮助

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

感谢你的帮助。

更新:

样本值为 2.2000012095022 E + 26

556160 次浏览

尝试使用 STR()函数。

SELECT STR(float_field, 25, 5)

STR ()功能


另一个注意事项: 左边的这个带有空格的垫子。如果这是一个与 LTRIM组合的问题:

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

Float 只有一个 max。15位数字的精度。第15位之后的数字因此是随机的,并且转换为 bigint (max。19位数字)或小数并不能帮助你。

有用的话题,谢谢。

如果你想像我一样移除导线零,你可以使用:

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

这样不用四舍五入也能有所帮助

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)

修改了 Axel 的响应,因为它在某些情况下会产生不良的结果。

DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;


SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM((REPLACE(CAST(CAST(@MyFloat AS DECIMAL(38,18)) AS VARCHAR(max)), '0', ' '))), ' ', '0'),'.',' ')),' ','.')
select replace(myFloat, '', '')

来自 REPLACE ()文档:

如果输入参数之一是 nvarchar 数据类型,则返回 nvarchar; 否则,REPLACE 返回 varchar。
如果任何一个参数为 NULL,则返回 NULL。

测试:
NULL = = > [ NULL ]
1.11 = = > 1.11
1.10 = = > 1.1
1.00 = = > 1
0.00 = = > 0
-1.10 = = > -1.1
0.00001 = = > 1e-005
0.000011 = = > 1.1e-005

如果使用 CLR 函数,可以将 float 转换为与 float 类似的字符串,而不需要在末尾添加所有额外的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% 的 FP 编号(接近100,000个值)看起来与字符串值相同,就像它们在数据库中的 FP 编号一样。

先转换成 integer,然后再转换成 string:

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

我找到的唯一返回 EXACT 相同原始数字的查询位是

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)

应该在新的 SQLServer 版本中使用(Azure SQL 数据库,从 SQLServer2016RC3开始)

选择
作为 varchar (20)进行强制转换(替换(转换(十进制(15,2) ,acs _ daily _ debit) ,’.’,’,’))

来自 acs _ Balance _ Details

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

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

产出:

1000000000.1234

这有进一步的优势(在我的例子中) ,使数千个分隔符和本地化变得容易:

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

产出:

1.000.000.000,1234

试试这个,应该可以:

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

基于分子的答案:

DECLARE @F FLOAT = 1000000000.1234;
SELECT @F AS Original, CAST(FORMAT(@F, N'#.##############################') AS VARCHAR) AS Formatted;


SET @F = 823399066925.049
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;


SET @F = 0.502184537571209
SELECT @F AS Original, CAST(@F AS VARCHAR) AS Formatted
UNION ALL SELECT @F AS Original, CONVERT(VARCHAR(128), @F, 128) AS Formatted
UNION ALL SELECT @F AS Original, CAST(FORMAT(@F, N'G') AS VARCHAR) AS Formatted;

我只是遇到了类似的情况,并且对 SSMS v17.9.1/SQL 2017中提供的“非常大的数字”的舍入问题感到惊讶。

我不是建议我有一个解决方案,但我已经观察到,格式 礼物一个数字,似乎是正确的。我不能暗示这会减少进一步的舍入问题,或者在一个复杂的数学函数中是有用的。

T SQL 代码提供了哪些 应该清楚地证明了我的观察,同时使其他人能够测试他们的代码和想法,如果需要出现。

WITH Units AS
(
SELECT 1.0 AS [RaisedPower] , 'Ten' As UnitDescription
UNION ALL
SELECT 2.0 AS [RaisedPower] , 'Hundred' As UnitDescription
UNION ALL
SELECT 3.0 AS [RaisedPower] , 'Thousand' As UnitDescription
UNION ALL
SELECT 6.0 AS [RaisedPower] , 'Million' As UnitDescription
UNION ALL
SELECT 9.0 AS [RaisedPower] , 'Billion' As UnitDescription
UNION ALL
SELECT 12.0 AS [RaisedPower] , 'Trillion' As UnitDescription
UNION ALL
SELECT 15.0 AS [RaisedPower] , 'Quadrillion' As UnitDescription
UNION ALL
SELECT 18.0 AS [RaisedPower] , 'Quintillion' As UnitDescription
UNION ALL
SELECT 21.0 AS [RaisedPower] , 'Sextillion' As UnitDescription
UNION ALL
SELECT 24.0 AS [RaisedPower] , 'Septillion' As UnitDescription
UNION ALL
SELECT 27.0 AS [RaisedPower] , 'Octillion' As UnitDescription
UNION ALL
SELECT 30.0 AS [RaisedPower] , 'Nonillion' As UnitDescription
UNION ALL
SELECT 33.0  AS [RaisedPower] , 'Decillion' As UnitDescription


)


SELECT UnitDescription


,              POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )                                                             AS ReturnsFloat
,        CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  AS NUMERIC (38,0) )                                        AS RoundingIssues
, STR(   CAST( POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  AS NUMERIC (38,0) ) ,   CAST([RaisedPower] AS INT) + 2, 0) AS LessRoundingIssues
, FORMAT(      POWER( CAST(10.0 AS FLOAT(53)) , [RaisedPower] )  , '0')                                                     AS NicelyFormatted


FROM Units
ORDER BY [RaisedPower]
SELECT LTRIM(STR(float_field, 25, 0))

是最好的方法,所以你不加上 .0000和任何数字结束的价值。