SQL Server'da float'ı varchar'a dönüştürme


130

Sayıları farklı uzunlukta olan bir float sütunum var ve onları varchar'a dönüştürmeye çalışıyorum.

Bazı değerler bigint max boyutunu aşıyor, bu yüzden böyle bir şey yapamam

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

Ondalık kullanmayı denedim, ancak sayılar aynı boyutta değil, bu yüzden bu da yardımcı olmuyor

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

Herhangi bir yardım takdir edilmektedir.

GÜNCELLEME:

Örnek değer 2.2000012095022E + 26'dır .


cast(float_field as varchar(max))aksi halde soruyu anlamıyorum
Denis Valeev

5
dökümünüz için değer 2.2e + 026. Muhtemelen
soruyu anlamadınız

Yanıtlar:


247

STR()İşlevi kullanmayı deneyin .

SELECT STR(float_field, 25, 5)

STR () İşlevi


Başka bir not: bu solda boşluklu pedler. Bu bir sorunsa şunlarla birleştirin LTRIM:

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

3
Bende var ************************* . Bu da ne? :)
hgulyan

4
@hgulyan - Select LTRIM(Str(float_field, 38, 0))Verileriniz için çalışıyor mu ?
Martin Smith

@Martin Smith, Çalışıyor gibi görünüyor, ancak ondalık ile aynı şekilde, bu yüzden gerçek değer olup olmadığından emin değilim (son on rakam sıfırdır). Sanırım gerçek değer kaybedildi. Teşekkür ederim!
hgulyan

2
@hgulyan -son on hane sıfırdır çünkü Strfonksiyondaki son parametre budur . Ondalık noktadan sonraki basamak sayısı. Gönderdiğim bağlantıyı okudun mu? Select LTRIM(Str(float_field, 38, 10))
Sıfırı

4
Keşke SSMS'de bir uyarı olsaydı, "hey, bu hatalı telefon alanını metne çevirdiğinizde, bilimsel gösterimle güzel bir telefon numarası almaya hazır olun! Önce ltrim (str) 'i yapacak kadar akıllı değiliz" ...
pkExec

42

Tam olarak aynı orijinal sayıyı döndüren bulduğum tek sorgu biti

CONVERT (VARCHAR(50), float_field,128)

Bkz. Http://www.connectsql.com/2011/04/normal-0-microsoftinternetexplorer4.html

Yukarıdaki diğer çözümler bazen sonda rakamları yuvarlar veya ekler

GÜNCELLEME : Aşağıdaki yorumlara ve https://msdn.microsoft.com/en-us/library/ms187928.aspx'de görebileceklerime göre :

CONVERT (VARCHAR(50), float_field,3)

Yeni SQL Server sürümlerinde (Azure SQL Veritabanı ve SQL Server 2016 RC3'ten itibaren) kullanılmalıdır


2
@Adinas için +1, float değeri olduğu gibi dönüştürülür, ancak 0float değeri olarak dönüştürülür 0.0E0. Float alanını, ne zaman ve olduğu gibi varchargörüntülemem gereken hale dönüştürmem gerekiyordu . Bunu sorguya aşağıdaki gibi ifade ekleyerek başardım ; NANULL0CASECASE 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 02

2
Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspx belgesine göre , 128 sözdizimi eski nedenlerden dolayı dahil edilmiştir ve gelecekteki bir sürümde kaldırılabilir
Mike Turner

1
128 kullanımdan kaldırılmıştır, ancak en son SQL Server sürümlerinde bunun yerine 3 adet gibi görünmektedir.
user3524983

13

Bu, sqlserver 2012'de kullandığım çözümdü (çünkü diğer tüm öneriler, kesirli kısmı kısaltma dezavantajına veya başka bir dezavantaja sahipti).

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

çıktı:

1000000000.1234

bu, binlerce ayırıcıyı ve yerelleştirmeyi kolaylaştırmak için (benim durumumda) daha fazla avantaja sahiptir:

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

çıktı:

1.000.000.000,1234

3

Faydalı konu teşekkürler.

Eğer benim gibi sıfırın başını kaldırmak istiyorsanız, bunu kullanabilirsiniz:

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

2

float yalnızca maks. 15 basamaklı hassasiyet. 15. konumdan sonraki rakamlar bu nedenle rastgeledir ve bigint (maks. 19 hane) veya ondalık sayıya dönüştürme size yardımcı olmaz.


Ben anlamadım Alan değeri 2.2000012095022E + 26'dır. Çözüm nedir? Hiç yok mu?
hgulyan

dizgeye dönüştürerek, orijinal değerde saklanan rakamlardan daha fazla rakam elde edemezsiniz.
devio

Yani 15. pozisyondan sonra rakamlarımı kaybettim?
hgulyan

Verilerle ilgili bir tür sorun vardı. Bu değeri 15 haneli bir kayan nokta ile güncellemem gerekiyor. Cevabınızı kabul edeceğim, çünkü bu verilerle yaşadığım ana sorunu açıklıyor. Teşekkür ederim.
hgulyan

2

Bu, yuvarlamadan yardımcı olabilir

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

Bir içine dönüştürme integerbir içine ilk ve sonra string:

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

Bu, varsa ondalık sayıdan sonraki rakamları kaldıracaktır. Dolayısıyla bu çözüm doğru değildir.
RushabhG

2

Bunu deneyin, çalışmalı:

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

1

Bir CLR işlevi kullanırsanız, kayan noktayı, sondaki tüm fazladan 0'lar olmadan, aynı float gibi görünen bir dizeye dönüştürebilirsiniz.

CLR İşlevi

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

.

Misal

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

.

Çıktı

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

.

Uyarı

Dönüştürülen tüm dizeler 18 ondalık basamakta kesilir ve sonunda sıfır yoktur. 18 basamaklı hassasiyet bizim için sorun değil. Ve FP numaralarımızın% 100'ü (100.000 değere yakın), veri tabanında FP numaraları olarak olduğu gibi dize değerleriyle aynı görünür.


0

Bazı durumlarda istenmeyen sonuçlar doğuracağından, Axel'in tepkisinin biraz değiştirilmesi.

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

dan belgeleri) (DEĞİŞTİRME :

Giriş bağımsız değişkenlerinden biri nvarchar veri türündeyse nvarchar döndürür; aksi takdirde DEĞİŞTİR, varchar değerini döndürür.
Bağımsız değişkenlerden herhangi biri NULL ise NULL döndürür.

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


Varchar (20) olarak cast'i seçin ((decimal (15,2), acs_daily_debit), '.', ',') Değiştirin)

acs_balance_details'den


0

Moleküler cevaba göre:

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

Benzer bir durumla karşılaştım ve SSMS v17.9.1 / SQL 2017'de sunulan 'çok büyük sayıların' yuvarlanma sorunlarına şaşırdım.

Bir çözümüm olduğunu önermiyorum , ancak FORMAT'ın sunduğunu gözlemledim doğru görünen bir sayı . Bunun daha fazla yuvarlama sorunlarını azalttığını veya karmaşık bir matematiksel işlevde yararlı olduğunu ima edemem.

İhtiyaç duyulması halinde başkalarının kodlarını ve fikirlerini test etmelerine olanak sağlarken, gözlemlerimi açıkça göstermesi gereken T SQL Kodu sağlandı .

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

en iyi yoldur, böylece .0000değerin sonuna herhangi bir rakam eklemeyin .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.