Come convertire float in varchar in SQL Server


130

Ho una colonna float con numeri di diversa lunghezza e sto provando a convertirli in varchar.

Alcuni valori superano la dimensione massima di bigint, quindi non posso fare qualcosa del genere

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

Ho provato a usare i decimali, ma i numeri non hanno le stesse dimensioni, quindi anche questo non aiuta

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

Qualsiasi aiuto è apprezzato.

AGGIORNARE:

Il valore del campione è 2.2000012095022E + 26 .


cast(float_field as varchar(max))altrimenti non capisco la domanda
Denis Valeev,

5
il valore per il tuo cast è 2,2e + 026. Probabilmente non avrai la domanda :)
hgulyan,

Risposte:


247

Prova a usare la STR()funzione.

SELECT STR(float_field, 25, 5)

Funzione STR ()


Un'altra nota: questo pad a sinistra con spazi. Se questo è un problema, combinalo con LTRIM:

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

3
Ho ottenuto ************************* . Cos'è quello? :)
hgulyan,

4
@hgulyan - Funziona Select LTRIM(Str(float_field, 38, 0))con i tuoi dati?
Martin Smith,

@Martin Smith, sembra funzionare, ma allo stesso modo dei decimali, quindi non sono sicuro che sia il valore reale (le ultime dieci cifre sono zero). Immagino che il valore reale sia stato perso. Grazie!
hgulyan,

2
@hgulyan -le ultime dieci cifre sono zero perché questo è l'ultimo parametro della Strfunzione. Il numero di cifre dopo il punto decimale. Hai letto il link che ho pubblicato? Cambia lo zero in 10. Select LTRIM(Str(float_field, 38, 10))
codingbadger

4
Vorrei che ci fosse un avvertimento in SSMS "hey, quando converti quel campo telefonico float errato in testo, preparati a ottenere un bel numero di telefono con notazione scientifica! Non siamo abbastanza intelligenti da ltrim (str) prima" ...
pkExec,

42

L'unico bit di query che ho trovato che restituisce lo stesso numero originale EXACT è

CONVERT (VARCHAR(50), float_field,128)

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

Le altre soluzioni di cui sopra a volte arrotondano o aggiungono cifre alla fine

AGGIORNAMENTO : Come da commenti di seguito e cosa posso vedere in https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Dovrebbe essere usato nelle nuove versioni di SQL Server (database SQL di Azure e a partire da SQL Server 2016 RC3)


2
+1 per @adinas, il valore float viene convertito come tale, ma ad eccezione del 0valore float convertito come 0.0E0. Avevo bisogno di convertire il campo float in varcharcome ho bisogno di visualizzare NAquando NULLe 0come è. Ho raggiunto questo aggiungendo una CASEdichiarazione nella query come di seguito; 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
Secondo il documento su Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspx , la sintassi 128 è inclusa per motivi legacy e potrebbe essere deprecata in una versione futura
Mike Turner

1
128 è obsoleto ma 3 sembra sostituirlo nelle versioni più recenti di SQL Server.
user3524983,

13

questa è la soluzione che ho finito per usare in sqlserver 2012 (dal momento che tutti gli altri suggerimenti avevano lo svantaggio di troncare la parte frazionaria o qualche altro inconveniente).

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

produzione:

1000000000.1234

questo ha l'ulteriore vantaggio (nel mio caso) di semplificare la separazione e la localizzazione di migliaia:

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

produzione:

1.000.000.000,1234

3

Argomento utile grazie.

Se vuoi come me rimuovere zero delle derivazioni puoi usare quello:

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

2

float ha solo un max. precisione di 15 cifre. Le cifre dopo la 15a posizione sono quindi casuali e la conversione in bigint (massimo 19 cifre) o decimale non ti aiuta.


Non capisco Il valore del campo è 2.2000012095022E + 26. Qual è la soluzione? Non ce n'è?
hgulyan,

non è possibile ottenere più cifre convertendo in stringa di quante sono le cifre memorizzate nel valore originale.
Devio,

Quindi ho perso le cifre dopo la 15a posizione?
hgulyan,

Si è verificato un problema con i dati. Devo solo aggiornare quel valore con un float di 15 cifre. Accetterò la tua risposta, perché descrive il problema principale che ho avuto con questi dati. Grazie.
hgulyan,

2

Questo può aiutare senza arrotondare

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

Converti integerprima in e poi in string:

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

Ciò rimuoverà le cifre dopo il decimale, se presenti. Quindi, questa soluzione non è accurata.
RushabhG,

2

Prova questo, dovrebbe funzionare:

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

1

Se si utilizza una funzione CLR, è possibile convertire il float in una stringa simile al float, senza tutti gli 0 in più alla fine.

Funzione 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; }
}

.

Esempio

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

.

Produzione

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

.

Avvertimento

Tutte le stringhe convertite vengono troncate con 18 cifre decimali e non vi sono zeri finali. 18 cifre di precisione non sono un problema per noi. Inoltre, il 100% dei nostri numeri FP (vicino a 100.000 valori) sembrano identici ai valori stringa come nel database come numeri FP.


0

La risposta di Axel modificata un po 'in quanto in alcuni casi produrrà risultati indesiderati.

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

dalla documentazione di REPLACE () :

Restituisce nvarchar se uno degli argomenti di input è del tipo di dati nvarchar; altrimenti, REPLACE restituisce varchar.
Restituisce NULL se uno qualsiasi degli argomenti è NULL.

test:
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


0

Seleziona
cast (sostituisci (converti (decimale (15,2), acs_daily_debit), '.', ',') Come varchar (20))

da acs_balance_details


0

Basato sulla risposta molecolare:

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

Mi sono appena imbattuto in una situazione simile e sono rimasto sorpreso dai problemi di arrotondamento di "numeri molto grandi" presentati in SSMS v17.9.1 / SQL 2017.

Non sto suggerendo di avere una soluzione, tuttavia ho osservato che FORMATO presenta un numero che appare corretto. Non posso implicare che ciò riduca ulteriori problemi di arrotondamento o sia utile all'interno di una complicata funzione matematica.

Fornito il codice SQL che dovrebbe dimostrare chiaramente le mie osservazioni, consentendo agli altri di testare il loro codice e le idee in caso di necessità.

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))

è il modo migliore per non aggiungere .0000e nessuna cifra alla fine del valore.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.