Cách chuyển đổi float sang varchar trong SQL Server


130

Tôi có một cột float với các số có độ dài khác nhau và tôi đang cố gắng chuyển đổi chúng thành varchar.

Một số giá trị vượt quá kích thước tối đa của bigint, vì vậy tôi không thể làm điều gì đó như thế này

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

Tôi đã thử sử dụng số thập phân, nhưng các số không có cùng kích thước, vì vậy điều này cũng không giúp được gì

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

Bất kỳ trợ giúp được đánh giá cao.

CẬP NHẬT:

Giá trị mẫu là 2.2000012095022E + 26 .


cast(float_field as varchar(max))nếu không thì tôi không nhận được câu hỏi
Denis Valeev

5
giá trị cho dàn diễn viên của bạn là 2.2e + 026. Có lẽ bạn không nhận được câu hỏi :)
hgulyan

Câu trả lời:


246

Hãy thử sử dụng STR()chức năng.

SELECT STR(float_field, 25, 5)

Hàm STR ()


Một lưu ý khác: miếng đệm này ở bên trái có khoảng trắng. Nếu đây là một vấn đề kết hợp với LTRIM:

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

3
Tôi đã nhận ************************* . Cái gì vậy :)
hgulyan

4
@hgulyan - Có Select LTRIM(Str(float_field, 38, 0))hoạt động cho dữ liệu của bạn không?
Martin Smith

@Martin Smith, Nó có vẻ hoạt động, nhưng giống như số thập phân, vì vậy tôi không chắc đó có phải là giá trị thực hay không (mười chữ số cuối cùng bằng 0). Tôi đoán rằng giá trị thực đã bị mất. Cảm ơn bạn!
hgulyan

2
@hgulyan - mười chữ số cuối cùng bằng 0 vì đó là tham số cuối cùng trong Strhàm. Số chữ số sau dấu thập phân. Bạn đã đọc các liên kết tôi đăng? Thay đổi số 0 thành 10. Select LTRIM(Str(float_field, 38, 10))
codbadger

4
Tôi ước có một cảnh báo trong SSMS "này, khi bạn chuyển đổi trường điện thoại nổi bị lỗi đó thành văn bản, hãy chuẩn bị để có được một số điện thoại đẹp với ký hiệu khoa học! Chúng tôi không đủ thông minh để ltrim (str) trước" ...
pkExec

42

Bit truy vấn duy nhất tôi tìm thấy trả về cùng số chính xác là

CONVERT (VARCHAR(50), float_field,128)

Xem http://www.connectsql.com/2011/04/n normal-0-microsoftiNETexplorer4.html

Các giải pháp khác ở trên đôi khi sẽ làm tròn hoặc thêm chữ số ở cuối

CẬP NHẬT : Theo nhận xét bên dưới và những gì tôi có thể thấy trong https://msdn.microsoft.com/en-us/l Library / ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Nên được sử dụng trong các phiên bản SQL Server mới (Cơ sở dữ liệu Azure SQL và bắt đầu trong SQL Server 2016 RC3)


2
+1 cho @adinas, giá trị float được chuyển đổi như nó nhưng ngoại trừ 0giá trị float được chuyển đổi thành 0.0E0. Tôi cần phải chuyển đổi trường float thành varcharnhư tôi cần để hiển thị NAkhi NULL0như nó là. Tôi đã đạt được điều này bằng cách thêm CASEcâu lệnh trong truy vấn như dưới đây; 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
Theo tài liệu trên Microsoft - msdn.microsoft.com/en-us/l Library / ms187928.aspx, cú pháp 128 được đưa vào vì lý do di sản và có thể bị phản đối trong phiên bản tương lai
Mike Turner

1
128 không được dùng nữa nhưng 3 dường như là sự thay thế cho nó trong các bản phát hành SQL Server gần đây nhất.
dùng3524983

13

đây là giải pháp tôi đã sử dụng trong sqlserver 2012 (vì tất cả các đề xuất khác đều có nhược điểm là cắt bớt một phần phân số hoặc một số nhược điểm khác).

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

đầu ra:

1000000000.1234

điều này có lợi thế hơn nữa (trong trường hợp của tôi) để làm cho hàng ngàn dấu phân tách và bản địa hóa dễ dàng:

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

đầu ra:

1.000.000.000,1234

3

Chủ đề hữu ích cảm ơn.

Nếu bạn muốn như tôi loại bỏ chì, bạn có thể sử dụng:

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

2

float chỉ có max. độ chính xác 15 chữ số. Do đó, các chữ số sau vị trí thứ 15 là ngẫu nhiên và chuyển đổi sang bigint (tối đa 19 chữ số) hoặc số thập phân không giúp ích gì cho bạn.


Tôi không hiểu Giá trị trường là 2.2000012095022E + 26. Giải pháp là gì? Có không?
hgulyan

bạn không thể có được nhiều chữ số hơn bằng cách chuyển đổi thành chuỗi hơn là các chữ số được lưu trữ trong giá trị ban đầu.
devio

Vì vậy, tôi đã mất chữ số sau vị trí thứ 15?
hgulyan

Có một số loại vấn đề với dữ liệu. Tôi chỉ cần cập nhật giá trị đó với số float 15 chữ số. Tôi sẽ chấp nhận câu trả lời của bạn, vì nó mô tả vấn đề chính tôi gặp phải với dữ liệu này. Cảm ơn bạn.
hgulyan

2

Điều này có thể giúp đỡ mà không làm tròn

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

Chuyển đổi thành integerđầu tiên và sau đó thành string:

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

Điều này sẽ loại bỏ các chữ số sau số thập phân, nếu có. Do đó, giải pháp này không chính xác.
RushabhG

2

Hãy thử cái này, nên hoạt động:

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

1

Nếu bạn sử dụng hàm CLR, bạn có thể chuyển đổi float thành một chuỗi trông giống như float, không có tất cả 0 0 ở cuối.

Chức năng 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; }
}

.

Thí dụ

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

.

Đầu ra

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

.

Hãy cẩn thận

Tất cả các chuỗi chuyển đổi được cắt ngắn ở 18 vị trí thập phân và không có số 0 ở cuối. 18 chữ số chính xác không phải là vấn đề đối với chúng tôi. Và, 100% số FP của chúng tôi (gần 100.000 giá trị) trông giống hệt như các giá trị chuỗi như chúng làm trong cơ sở dữ liệu dưới dạng số FP.


0

Phản ứng của Axel đã sửa đổi một chút vì trong một số trường hợp nhất định sẽ tạo ra kết quả không mong muốn.

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

từ tài liệu REPLACE () :

Trả về nvarchar nếu một trong các đối số đầu vào thuộc kiểu dữ liệu nvarchar; mặt khác, REPLACE trả về varchar.
Trả về NULL nếu bất kỳ một trong các đối số là NULL.

kiểm tra:
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

Chọn
cast (thay thế (chuyển đổi (thập phân (15,2), acs_daily_debit), '.', ',') Là varchar (20))

từ acs_balance_details


0

Dựa trên câu trả lời của phân tử:

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

Tôi vừa gặp một tình huống tương tự và rất ngạc nhiên về các vấn đề làm tròn số 'số lượng rất lớn' được trình bày trong SSMS v17.9.1 / SQL 2017.

Tôi không gợi ý rằng tôi có một giải pháp, tuy nhiên tôi đã quan sát thấy FORMAT trình bày một con số có vẻ đúng. Tôi không thể ngụ ý điều này làm giảm các vấn đề làm tròn thêm hoặc hữu ích trong một hàm toán học phức tạp.

Mã SQL được cung cấp sẽ thể hiện rõ ràng các quan sát của tôi trong khi cho phép người khác kiểm tra mã và ý tưởng của họ khi có nhu cầu.

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

là cách tốt nhất để bạn không thêm .0000và bất kỳ chữ số nào ở cuối giá trị.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.