So konvertieren Sie float in varchar in SQL Server

130

Ich habe eine Float-Spalte mit Nummern unterschiedlicher Länge und versuche, sie in Varchar umzuwandeln.

Einige Werte überschreiten die maximale Größe von bigint, daher kann ich so etwas nicht tun

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

Ich habe versucht, Dezimalzahlen zu verwenden, aber Zahlen sind nicht gleich groß, daher hilft dies auch nicht

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

Jede Hilfe wird geschätzt.

AKTUALISIEREN:

Der Beispielwert ist 2.2000012095022E + 26 .

hgulyan
quelle
cast(float_field as varchar(max))sonst bekomme ich die Frage nicht
Denis Valeev
5
Der Wert für Ihre Besetzung ist 2.2e + 026. Wahrscheinlich bekommen Sie die Frage nicht :)
hgulyan

Antworten:

246

Versuchen Sie es mit der STR()Funktion.

SELECT STR(float_field, 25, 5)

STR () Funktion


Noch ein Hinweis: Dieses Feld ist links mit Leerzeichen versehen. Wenn dies ein Problem ist, kombinieren Sie mit LTRIM:

SELECT LTRIM(STR(float_field, 25, 5))
Codierungsbadger
quelle
3
Ich habe ************************* . Was ist das? :)
Hgulyan
4
@hgulyan - Funktioniert Select LTRIM(Str(float_field, 38, 0))für Ihre Daten?
Martin Smith
@ Martin Smith, es scheint zu funktionieren, aber genauso wie die Dezimalzahl, daher bin ich mir nicht sicher, ob es der tatsächliche Wert ist (die letzten zehn Ziffern sind Null). Ich denke, dass der wahre Wert verloren gegangen ist. Danke dir!
Hgulyan
2
@hgulyan - Die letzten zehn Ziffern sind Null, da dies der letzte Parameter in der StrFunktion ist. Die Anzahl der Stellen nach dem Dezimalpunkt. Hast du den Link gelesen, den ich gepostet habe? Ändern Sie die Null auf 10. Select LTRIM(Str(float_field, 38, 10))
Codierungsbadger
4
Ich wünschte, es gäbe eine Warnung in SSMS: "Hey, wenn Sie dieses fehlerhafte Float-Telefonfeld in Text umwandeln, seien Sie darauf vorbereitet, eine nette Telefonnummer mit wissenschaftlicher Notation zu erhalten! Wir sind nicht klug genug, zuerst (str) zu trimmen" ...
pkExec
42

Das einzige Abfragebit, das ich gefunden habe und das genau dieselbe ursprüngliche Nummer zurückgibt, ist

CONVERT (VARCHAR(50), float_field,128)

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

Die anderen oben genannten Lösungen runden manchmal ab oder fügen am Ende Ziffern hinzu

UPDATE : Gemäß den Kommentaren unten und dem, was ich unter https://msdn.microsoft.com/en-us/library/ms187928.aspx sehen kann :

CONVERT (VARCHAR(50), float_field,3)

Sollte in neuen SQL Server-Versionen verwendet werden (Azure SQL-Datenbank und ab SQL Server 2016 RC3)

adinas
quelle
2
+1 für @adinas wird der Float-Wert so konvertiert, wie er ist, mit Ausnahme des 0Float-Werts, der als konvertiert wird 0.0E0. Ich musste das Float-Feld varcharso konvertieren, dass es angezeigt wird, NAwann NULLund 0wie es ist. Ich habe dies erreicht, indem ich CASEder folgenden Abfrage eine Anweisung hinzugefügt habe . 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
Laut dem Dokument auf Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspx ist die 128-Syntax aus älteren Gründen enthalten und wird möglicherweise in einer zukünftigen Version
Mike Turner,
1
128 ist veraltet, aber 3 scheint der Ersatz dafür in den neuesten SQL Server-Versionen zu sein.
user3524983
13

Dies ist die Lösung, die ich in sqlserver 2012 verwendet habe (da alle anderen Vorschläge den Nachteil hatten, einen Bruchteil oder einen anderen Nachteil abzuschneiden).

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

Ausgabe:

1000000000.1234

Dies hat (in meinem Fall) den weiteren Vorteil, dass Tausende Trennzeichen und Lokalisierung einfach sind:

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

Ausgabe:

1.000.000.000,1234
molekular
quelle
3

Nützliches Thema danke.

Wenn du wie ich die Nullen entfernen willst, kannst du das verwenden:

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

float hat nur eine max. Genauigkeit von 15 Stellen. Ziffern nach der 15. Position sind daher zufällig, und die Konvertierung in Bigint (max. 19 Ziffern) oder Dezimalzahlen hilft Ihnen nicht weiter.

devio
quelle
Ich verstehe es nicht Der Feldwert ist 2.2000012095022E + 26. Was ist die Lösung? Es gibt keine?
Hgulyan
Sie können durch Konvertieren in eine Zeichenfolge nicht mehr Ziffern erhalten, als im ursprünglichen Wert Ziffern gespeichert sind.
Devio
Also habe ich nach dem 15. Platz Ziffern verloren?
Hgulyan
Es gab ein Problem mit den Daten. Ich muss diesen Wert nur mit einem 15-stelligen Float aktualisieren. Ich werde Ihre Antwort akzeptieren, da sie das Hauptproblem beschreibt, das ich mit diesen Daten hatte. Danke dir.
Hgulyan
2

Dies kann ohne Rundung helfen

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
quelle
2

Konvertieren Sie in eine integererste und dann in eine string:

cast((convert(int,b.tax_id)) as varchar(20))
Amit Patil
quelle
Dadurch werden die Ziffern nach der Dezimalstelle entfernt, falls vorhanden. Daher ist diese Lösung nicht genau.
RushabhG
2

Versuchen Sie dieses, sollte funktionieren:

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

Wenn Sie eine CLR-Funktion verwenden, können Sie den Float in einen String konvertieren, der genau wie der Float aussieht, ohne alle zusätzlichen Nullen am Ende.

CLR-Funktion

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

.

Beispiel

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

.

Ausgabe

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

.

Vorbehalt

Alle konvertierten Zeichenfolgen werden mit 18 Dezimalstellen abgeschnitten, und es gibt keine nachgestellten Nullen. 18 Stellen Genauigkeit sind für uns kein Problem. Und 100% unserer FP-Nummern (fast 100.000 Werte) sehen als Zeichenfolgenwerte genauso aus wie in der Datenbank als FP-Nummern.

James L.
quelle
0

Die Reaktion von Axel wurde in bestimmten Fällen etwas geändert, was zu unerwünschten Ergebnissen führt.

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

aus der Dokumentation zu REPLACE () :

Gibt nvarchar zurück, wenn eines der Eingabeargumente vom Datentyp nvarchar ist. Andernfalls gibt REPLACE varchar zurück.
Gibt NULL zurück, wenn eines der Argumente NULL ist.

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

Dinah
quelle
0

Wählen Sie
cast (replace (convert (decimal (15,2), acs_daily_debit), '.', ',') Als varchar (20)).

von acs_balance_details

Eduardo
quelle
0

Basierend auf der Antwort von 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
quelle
0

Ich bin gerade auf eine ähnliche Situation gestoßen und war überrascht über die Rundungsprobleme von "sehr großen Zahlen", die in SSMS v17.9.1 / SQL 2017 vorgestellt wurden.

Ich behaupte nicht , ich eine Lösung haben, aber ich , dass beobachtet FORMAT präsentiert eine Zahl , die korrekt angezeigt wird . Ich kann nicht implizieren, dass dies weitere Rundungsprobleme reduziert oder innerhalb einer komplizierten mathematischen Funktion nützlich ist.

T SQL - Code geliefert, sollte klar meine Beobachtungen zeigen , während andere ermöglichen , ihren Code zu testen und Ideen die Notwendigkeit entstehen sollte.

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

ist der beste Weg, damit Sie .0000keine Ziffer am Ende des Werts hinzufügen .

RUBEN
quelle