Bagaimana mengkonversi float ke varchar di SQL Server

130

Saya memiliki kolom apung dengan jumlah panjang yang berbeda dan saya mencoba mengubahnya menjadi varchar.

Beberapa nilai melebihi ukuran maksimal bigint, jadi saya tidak bisa melakukan hal seperti ini

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

Saya sudah mencoba menggunakan desimal, tetapi jumlahnya tidak dengan ukuran yang sama, jadi ini tidak membantu juga

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

Bantuan apa pun dihargai.

MEMPERBARUI:

Nilai sampel adalah 2.2000012095022E + 26 .

hgulyan
sumber
cast(float_field as varchar(max))kalau tidak, saya tidak mendapatkan pertanyaan
Denis Valeev
5
nilai untuk pemain Anda adalah 2.2e + 026. Mungkin Anda tidak mendapatkan pertanyaannya :)
hgulyan

Jawaban:

246

Coba gunakan STR()fungsinya.

SELECT STR(float_field, 25, 5)

STR () Berfungsi


Catatan lain: bantalan ini di sebelah kiri dengan spasi. Jika ini merupakan masalah, kombinasikan dengan LTRIM:

SELECT LTRIM(STR(float_field, 25, 5))
pembuat kode
sumber
3
Saya mendapatkan ************************* . Apa itu? :)
hgulyan
4
@hgulyan - Apakah Select LTRIM(Str(float_field, 38, 0))berfungsi untuk data Anda?
Martin Smith
@ Martin Smith, Tampaknya berfungsi, tetapi cara yang sama dengan desimal, jadi saya tidak yakin apakah itu nilai sebenarnya (sepuluh digit terakhir adalah nol). Saya kira, bahwa nilai sebenarnya hilang. Terima kasih!
hgulyan
2
@ hgulyan - sepuluh digit terakhir adalah nol karena untuk itulah parameter terakhir dalam Strfungsi. Jumlah digit setelah titik desimal. Apakah Anda membaca tautan yang saya poskan? Ubah nol menjadi 10. Select LTRIM(Str(float_field, 38, 10))
codingbadger
4
Saya berharap ada peringatan di SSMS "hei, ketika Anda mengonversi bidang telepon float yang keliru menjadi teks, bersiaplah untuk mendapatkan nomor telepon yang bagus dengan notasi ilmiah! Kami tidak cukup pintar untuk ltrim (str) terlebih dahulu" ...
pkExec
42

Satu-satunya bit permintaan yang saya temukan yang mengembalikan nomor asli yang sama persis adalah

CONVERT (VARCHAR(50), float_field,128)

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

Solusi lain di atas terkadang akan membulatkan atau menambah angka di bagian akhir

UPDATE : Sesuai komentar di bawah ini dan apa yang dapat saya lihat di https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Harus digunakan dalam versi SQL Server baru (Azure SQL Database, dan mulai di SQL Server 2016 RC3)

adinas
sumber
2
+1 untuk @adinas, nilai float dikonversi seperti itu tetapi dengan pengecualian 0nilai float dikonversi sebagai 0.0E0. Saya perlu mengubah bidang float menjadi varcharseperti yang saya butuhkan untuk menampilkan NAkapan NULLdan 0apa adanya. Saya mencapai ini dengan menambahkan CASEpernyataan dalam kueri seperti di bawah ini; 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
Menurut dokumen di Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspx , 128 sintaks disertakan untuk alasan lawas dan dapat dicabut dalam versi yang akan datang
Mike Turner
1
128 sudah usang tetapi 3 tampaknya menjadi pengganti untuk itu dalam rilis SQL Server terbaru.
user3524983
13

ini adalah solusi yang saya akhirnya gunakan di sqlserver 2012 (karena semua saran lain memiliki kelemahan memotong sebagian kecil atau beberapa kelemahan lainnya).

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

keluaran:

1000000000.1234

ini memiliki keuntungan lebih lanjut (dalam kasus saya) untuk membuat ribuan pemisah dan lokalisasi mudah:

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

keluaran:

1.000.000.000,1234
molekuler
sumber
3

Topik yang berguna terima kasih.

Jika Anda ingin saya menghapus leadings zero, Anda dapat menggunakannya:

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

float hanya memiliki maks. presisi 15 digit. Karena itu angka setelah posisi ke-15 acak, dan konversi ke bigint (maks. 19 angka) atau desimal tidak membantu Anda.

devio
sumber
Saya tidak mengerti. Nilai bidang adalah 2.2000012095022E + 26. Apa solusinya? Tidak ada?
hgulyan
Anda tidak bisa mendapatkan lebih banyak digit dengan mengonversi ke string daripada ada angka yang disimpan dalam nilai asli.
devio
Jadi saya kehilangan angka setelah posisi ke-15?
hgulyan
Ada beberapa jenis masalah dengan data. Saya hanya perlu memperbarui nilai itu dengan float 15 digit. Saya akan menerima jawaban Anda, karena ini menjelaskan masalah utama yang saya miliki dengan data ini. Terima kasih.
hgulyan
2

Ini bisa membantu tanpa pembulatan

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

Konversikan menjadi yang integerpertama dan kemudian menjadi string:

cast((convert(int,b.tax_id)) as varchar(20))
Amit Patil
sumber
Ini akan menghapus digit setelah desimal, jika ada. Karenanya, solusi ini tidak akurat.
RushabhG
2

Coba ini, harus bekerja:

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

Jika Anda menggunakan fungsi CLR, Anda dapat mengubah float menjadi string yang terlihat seperti float, tanpa semua 0 ekstra di akhir.

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

.

Contoh

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

.

Keluaran

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

.

Peringatan

Semua string yang dikonversi dipotong pada 18 tempat desimal, dan tidak ada nol tambahan. Presisi 18 digit bukanlah masalah bagi kami. Dan, 100% dari nomor FP kami (mendekati 100.000 nilai) terlihat sama dengan nilai string seperti yang mereka lakukan dalam basis data sebagai angka FP.

James L.
sumber
0

Respons Axel yang dimodifikasi sedikit untuk kasus-kasus tertentu akan menghasilkan hasil yang tidak diinginkan.

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

dari dokumentasi REPLACE () :

Mengembalikan nvarchar jika salah satu argumen input adalah dari tipe data nvarchar; jika tidak, REPLACE mengembalikan varchar.
Mengembalikan NULL jika salah satu argumennya adalah NULL.

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

Dina
sumber
0

Pilih
cast (ganti (convert (desimal (15,2), acs_daily_debit), '.', ',') Sebagai varchar (20))

dari acs_balance_details

Eduardo
sumber
0

Berdasarkan jawaban molekuler:

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;
pengguna8642458
sumber
0

Saya baru saja menemukan situasi yang sama dan terkejut dengan masalah pembulatan 'angka sangat besar' yang disajikan dalam SSMS v17.9.1 / SQL 2017.

Saya tidak menyarankan saya punya solusi, namun saya telah mengamati bahwa FORMAT menyajikan angka yang tampaknya benar. Saya tidak bisa menyiratkan ini mengurangi masalah pembulatan lebih lanjut atau berguna dalam fungsi matematika yang rumit.

Kode SQL T disediakan yang seharusnya menunjukkan dengan jelas pengamatan saya sementara memungkinkan orang lain untuk menguji kode mereka dan ide-ide harus muncul.

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

adalah cara terbaik sehingga Anda tidak menambahkan .0000dan angka apa pun di akhir nilai.

RUBEN
sumber