Cómo convertir flotante a varchar en SQL Server


130

Tengo una columna flotante con números de diferente longitud y estoy tratando de convertirlos a varchar.

Algunos valores exceden el tamaño máximo de bigint, así que no puedo hacer algo como esto

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

Intenté usar decimal, pero los números no son del mismo tamaño, por lo que esto tampoco ayuda

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

Cualquier ayuda es apreciada.

ACTUALIZAR:

El valor de la muestra es 2.2000012095022E + 26 .


cast(float_field as varchar(max))de lo contrario no tengo la pregunta
Denis Valeev

55
El valor de su lanzamiento es 2.2e + 026. Probablemente no consigas la pregunta :)
hgulyan

Respuestas:


246

Intenta usar la STR()función.

SELECT STR(float_field, 25, 5)

Función STR ()


Otra nota: esto rellena a la izquierda con espacios. Si esto es un problema, combine con LTRIM:

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

3
Tengo ************************* . ¿Que es eso? :)
hgulyan

44
@hgulyan - ¿Funciona Select LTRIM(Str(float_field, 38, 0))para tus datos?
Martin Smith

@ Martin Smith, parece funcionar, pero de la misma manera que el decimal, así que no estoy seguro de si es el valor real (los últimos diez dígitos son cero). Supongo que se perdió el valor real. ¡Gracias!
hgulyan

2
@hgulyan: los últimos diez dígitos son cero porque para eso está el último parámetro en la Strfunción. El número de dígitos después del punto decimal. ¿Leíste el enlace que publiqué? Cambie el cero a 10. Select LTRIM(Str(float_field, 38, 10))
codingbadger

44
Desearía que hubiera una advertencia en SSMS "oye, cuando conviertes ese campo de teléfono flotante erróneo en texto, ¡prepárate para obtener un buen número de teléfono con notación científica! No somos lo suficientemente inteligentes como para ltrim (str) primero" ...
pkExec

42

El único bit de consulta que encontré que devuelve el mismo número original EXACT es

CONVERT (VARCHAR(50), float_field,128)

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

Las otras soluciones anteriores a veces redondean o agregan dígitos al final

ACTUALIZACIÓN : Según los comentarios a continuación y lo que puedo ver en https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Debe usarse en nuevas versiones de SQL Server (Azure SQL Database, y comenzando en SQL Server 2016 RC3)


2
+1 para @adinas, el valor flotante se convierte como tal pero con la excepción del 0valor flotante convertido como 0.0E0. Necesitaba convertir el campo flotante a varcharcomo necesito mostrar NAcuándo NULLy 0cómo es. Lo logré agregando una CASEdeclaración en la consulta como se muestra a continuación; 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 acuerdo con el documento de Microsoft: msdn.microsoft.com/en-us/library/ms187928.aspx , la sintaxis de 128 está incluida por razones heredadas y puede ser eliminada en una versión futura
Mike Turner,

1
128 está en desuso pero 3 parece ser su reemplazo en las versiones más recientes de SQL Server.
user3524983

13

Esta es la solución que terminé usando en sqlserver 2012 (ya que todas las otras sugerencias tenían el inconveniente de truncar la parte fraccional o algún otro inconveniente).

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

salida:

1000000000.1234

Esto tiene la ventaja adicional (en mi caso) de facilitar la separación y la localización de miles:

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

salida:

1.000.000.000,1234

3

Tema útil gracias.

Si desea que yo elimine los encabezados cero, puede usar eso:

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

2

flotador solo tiene un máx. precisión de 15 dígitos. Por lo tanto, los dígitos después de la posición 15 son aleatorios, y la conversión a bigint (máx. 19 dígitos) o decimal no le ayuda.


No lo entiendo El valor del campo es 2.2000012095022E + 26. ¿Cual es la solución? No hay ninguno?
hgulyan

no puede obtener más dígitos al convertir en cadena que los dígitos almacenados en el valor original.
devio

¿Entonces he perdido dígitos después de la 15ª posición?
hgulyan

Hubo algún tipo de problema con los datos. Solo necesito actualizar ese valor con un flotante de 15 dígitos. Aceptaré tu respuesta, porque describe el problema principal que tuve con estos datos. Gracias.
hgulyan

2

Esto puede ayudar sin redondear

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

Convierte en un integerprimero y luego en un string:

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

Esto eliminará los dígitos después del decimal, si corresponde. Por lo tanto, esta solución no es precisa.
RushabhG

2

Prueba este, debería funcionar:

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

1

Si usa una función CLR, puede convertir el flotante en una cadena que se parezca al flotante, sin todos los 0 adicionales al final.

Función 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; }
}

.

Ejemplo

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

.

Salida

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

.

Consideración

Todas las cadenas convertidas se truncan a 18 decimales, y no hay ceros finales. 18 dígitos de precisión no son un problema para nosotros. Y, el 100% de nuestros números FP (cerca de 100,000 valores) se ven idénticos como valores de cadena como lo hacen en la base de datos como números FP.


0

La respuesta de Axel modificada un poco ya que para ciertos casos producirá resultados indeseables.

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'),'.',' ')),' ','.')

0
select replace(myFloat, '', '')

de la documentación REPLACE () :

Devuelve nvarchar si uno de los argumentos de entrada es del tipo de datos nvarchar; de lo contrario, REPLACE devuelve varchar.
Devuelve NULL si alguno de los argumentos es NULL.

pruebas:
nulo ==> [NULO]
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


0

Seleccione
cast (replace (convert (decimal (15,2), acs_daily_debit), '.', ',') Como varchar (20))

de acs_balance_details


0

Basado en la respuesta 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;

0

Acabo de encontrar una situación similar y me sorprendieron los problemas de redondeo de 'números muy grandes' presentados en SSMS v17.9.1 / SQL 2017.

No estoy sugiriendo que tenga una solución, sin embargo, he observado que FORMAT presenta un número que parece correcto. No puedo dar a entender que esto reduce más problemas de redondeo o es útil dentro de una función matemática complicada.

Se suministró un código SQL que debe demostrar claramente mis observaciones al tiempo que permite a otros probar su código e ideas en caso de necesidad.

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]

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

es la mejor manera de no agregar .0000ningún dígito al final del valor.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.