Como converter float em varchar no SQL Server

130

Eu tenho uma coluna flutuante com números de comprimento diferente e estou tentando convertê-los em varchar.

Alguns valores excedem o tamanho máximo de bigint, por isso não posso fazer algo assim

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

Eu tentei usar decimal, mas os números não são do mesmo tamanho, então isso também não ajuda

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

Qualquer ajuda é apreciada.

ATUALIZAR:

O valor da amostra é 2.2000012095022E + 26 .

hgulyan
fonte
cast(float_field as varchar(max))caso contrário eu não entendo a pergunta
Denis Valeev
5
o valor do seu elenco é 2,2e + 026. Provavelmente você não obter o quesion :)
hgulyan

Respostas:

246

Tente usar a STR()função

SELECT STR(float_field, 25, 5)

Função STR ()


Outra observação: esta almofada à esquerda com espaços. Se este for um problema, combine com LTRIM:

SELECT LTRIM(STR(float_field, 25, 5))
codingbadger
fonte
3
Eu tenho ************************* . O que é isso? :)
hgulyan
4
@ hgulyan - Funciona Select LTRIM(Str(float_field, 38, 0))para seus dados?
Martin Smith
@ Martin Smith, parece funcionar, mas da mesma forma que decimal, por isso não tenho certeza se é o valor real (últimos dez dígitos são zero). Eu acho que o valor real foi perdido. Obrigado!
precisa saber é o seguinte
2
@hgulyan - os últimos dez dígitos são zero, porque é para isso que serve o último parâmetro na Strfunção. O número de dígitos após o ponto decimal. Você leu o link que eu postei? Altere o zero para 10. Select LTRIM(Str(float_field, 38, 10))
codingbadger
4
Eu gostaria que houvesse um aviso no SSMS "hey, quando você converter esse campo telefónicas erradas float para texto, estar preparado para obter um número de telefone agradável com notação científica somos o suficiente para não inteligente para LTRIM (str) em primeiro lugar!" ...
pkExec 26/03
42

O único bit de consulta que encontrei que retorna exatamente o mesmo número original é

CONVERT (VARCHAR(50), float_field,128)

Consulte http://www.connectsql.com/2011/04/normal-0-microsoftinternetexplorer4.html

As outras soluções acima às vezes arredondam ou adicionam dígitos no final

ATUALIZAÇÃO : Conforme os comentários abaixo e o que posso ver em https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Deve ser usado em novas versões do SQL Server (Banco de Dados SQL do Azure e iniciando no SQL Server 2016 RC3)

adinas
fonte
2
+1 para @adinas, o valor flutuante é convertido como ele, mas com a exceção do 0valor flutuante sendo convertido como 0.0E0. Eu precisava converter o campo flutuante para varcharcomo eu precisava exibir NAquando NULLe 0como é. Eu consegui isso adicionando CASEinstrução na consulta como abaixo; 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
De acordo com o documento no Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspx , a sintaxe 128 está incluído por razões de legado e pode ser depreceated em uma versão futura
Mike Turner
1
128 foi descontinuado, mas 3 parece substituí-lo nas versões mais recentes do SQL Server.
user3524983
13

esta é a solução que acabei usando no sqlserver 2012 (já que todas as outras sugestões tinham a desvantagem de truncar parte fracionária ou outra desvantagem).

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

resultado:

1000000000.1234

isso tem a vantagem adicional (no meu caso) de facilitar a separação e a localização de milhares:

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

resultado:

1.000.000.000,1234
molecular
fonte
3

Tópico útil obrigado.

Se você quer que eu remova os leads zero, use:

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

o flutuador tem apenas um máx. precisão de 15 dígitos. Os dígitos após a 15ª posição são, portanto, aleatórios, e a conversão para bigint (máx. 19 dígitos) ou decimal não ajuda em nada.

devio
fonte
Eu não entendo. O valor do campo é 2.2000012095022E + 26. Qual a solução? Não tem?
precisa saber é o seguinte
você não pode obter mais dígitos convertendo para string do que os dígitos armazenados no valor original.
devio
Então, eu perdi dígitos após a 15ª posição?
precisa saber é o seguinte
Houve algum tipo de problema com os dados. Eu só preciso atualizar esse valor com uma flutuação de 15 dígitos. Aceito sua resposta, porque descreve o principal problema que tive com esses dados. Obrigado.
precisa saber é o seguinte
2

Isso pode ajudar sem arredondar

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)
Atul
fonte
2

Converta em um integerprimeiro e depois em um string:

cast((convert(int,b.tax_id)) as varchar(20))
Amit Patil
fonte
Isso removerá os dígitos após o decimal, se houver. Portanto, esta solução não é precisa.
RushabhG
2

Tente este, deve funcionar:

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

Se você usar uma função CLR, poderá converter o float em uma sequência que se pareça com o float, sem todos os 0 extra no final.

Função 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; }
}

.

Exemplo

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

.

Resultado

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

.

Embargo

Todas as cadeias convertidas são truncadas com 18 casas decimais e não há zeros à direita. 18 dígitos de precisão não são um problema para nós. E 100% de nossos números de FP (perto de 100.000 valores) parecem idênticos como valores de sequência de caracteres, como no banco de dados, como números de FP.

James L.
fonte
0

A resposta do Axel modificada um pouco, como em certos casos, produzirá resultados indesejáveis.

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'),'.',' ')),' ','.')
user2388752
fonte
0
select replace(myFloat, '', '')

da documentação REPLACE () :

Retorna nvarchar se um dos argumentos de entrada for do tipo de dados nvarchar; caso contrário, REPLACE retornará varchar.
Retorna NULL se qualquer um dos argumentos for NULL.

testes:
nulo ==> [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

Dinah
fonte
0

Selecione
conversão (substituir (converter (decimal (15,2), acs_daily_debit), '.', ',') Como varchar (20))

de acs_balance_details

Eduardo
fonte
0

Com base na resposta da molecular:

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;
user8642458
fonte
0

Acabei de me deparar com uma situação semelhante e fiquei surpreso com os problemas de arredondamento de 'números muito grandes' apresentados no SSMS v17.9.1 / SQL 2017.

Não estou sugerindo uma solução, mas observei que o FORMAT apresenta um número que parece correto. Não posso sugerir que isso reduza outros problemas de arredondamento ou seja útil em uma função matemática complicada.

T Código SQL fornecido, que deve demonstrar claramente minhas observações, permitindo que outras pessoas testem seu código e idéias, se necessário.

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]
Andrew
fonte
0
SELECT LTRIM(STR(float_field, 25, 0))

é a melhor maneira para você não adicionar .0000nenhum dígito no final do valor.

RUBEN
fonte