Как конвертировать float в varchar в SQL Server - PullRequest
115 голосов
/ 15 сентября 2010

У меня есть столбец с числами разной длины, и я пытаюсь преобразовать их в varchar.

Некоторые значения превышают максимальный размер bigint, поэтому я не могу сделать что-то подобное

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

Я пробовал использовать десятичную дробь, но числа не одного размера, так что это тоже не помогает

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

Любая помощь приветствуется.

UPDATE:

Пример значения 2.2000012095022E + 26 .

Ответы [ 14 ]

214 голосов
/ 15 сентября 2010

Попробуйте использовать функцию STR().

SELECT STR(float_field, 25, 5)

STR () Функция


Еще одно примечание: это колодки слева с пробелами. Если это проблема, объедините с LTRIM:

SELECT LTRIM(STR(float_field, 25, 5))
35 голосов
/ 23 июля 2014

Единственный найденный мной бит запроса, который возвращает ТОЧНОЕ исходное число, это

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 (база данных SQL Azure и начиная с SQL Server 2016 RC3)

12 голосов
/ 09 июля 2015

это решение, которое я использовал в sqlserver 2012 (поскольку все другие предложения имели недостаток усечения дробной части или какой-либо другой недостаток).

это имеет еще одно преимущество (в моем случае), облегчающее разделение тысяч и локализацию:

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

вывод:

1.000.000.000,1234
2 голосов
/ 18 июля 2014

Сначала преобразуйте в integer, а затем в string:

cast((convert(int,b.tax_id)) as varchar(20))
2 голосов
/ 22 февраля 2013

Это может помочь без округления

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)
2 голосов
/ 23 ноября 2012

Полезная тема спасибо.

Если вы хотите, чтобы я, как я, удалил нулевые пометки, вы можете использовать это:

DECLARE @MyFloat [float];
SET @MyFloat = 1000109360.050;
SELECT REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(LTRIM(REPLACE(STR(@MyFloat, 38, 16), '0', ' '))), ' ', '0'),'.',' ')),' ',',')
2 голосов
/ 15 сентября 2010

float имеет только макс. точность 15 цифр. Таким образом, цифры после 15-й позиции случайны, и преобразование в bigint (макс. 19 цифр) или десятичное не помогает.

1 голос
/ 06 июля 2017

Попробуйте это, должно работать:

cast((convert(bigint,b.tax_id)) as varchar(20))
1 голос
/ 13 июня 2014

Если вы используете функцию CLR, вы можете преобразовать число с плавающей точкой в ​​строку, которая выглядит точно так же, как и число без нуля в конце.

Функция 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.

0 голосов
/ 31 августа 2018

Я только что столкнулся с подобной ситуацией и был удивлен проблемами округления «очень больших чисел», представленных в SSMS v17.9.1 / SQL 2017.

Я не предполагаю, что у меня есть решение, однако я заметил, что FORMAT представляет число, которое кажется правильным. Я не могу подразумевать, что это уменьшает дальнейшие проблемы округления или полезно в сложной математической функции.

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]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...