วิธีการแปลง float เป็น varchar ใน SQL Server


130

ฉันมีคอลัมน์ลอยที่มีความยาวต่างกันและกำลังพยายามแปลงเป็น varchar

ค่าบางค่าเกินขนาด bigint max ก็เลยทำแบบนี้ไม่ได้

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

ฉันได้ลองใช้ทศนิยมแล้ว แต่ตัวเลขไม่ได้มีขนาดเท่ากันดังนั้นจึงไม่ช่วยเช่นกัน

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

ขอความช่วยเหลือใด ๆ

UPDATE:

ค่าตัวอย่างเป็น2.2000012095022E + 26


cast(float_field as varchar(max))มิฉะนั้นฉันจะไม่ได้รับคำถาม
Denis Valeev

5
ค่าร่ายของคุณคือ 2.2e + 026 คุณอาจไม่ได้รับ
คำถาม

คำตอบ:


247

ลองใช้STR()ฟังก์ชั่น

SELECT STR(float_field, 25, 5)

STR () ฟังก์ชัน


หมายเหตุอื่น: แผ่นอิเล็กโทรดด้านซ้ายมีช่องว่าง หากเป็นปัญหาร่วมกับLTRIM:

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

3
ฉันได้ ************************* . นั่นอะไร? :)
hgulyan

4
@hgulyan - Select LTRIM(Str(float_field, 38, 0))ทำงานกับข้อมูลของคุณหรือไม่
Martin Smith

@Martin Smith ดูเหมือนว่าจะใช้ได้ แต่ก็เหมือนกับทศนิยมดังนั้นฉันไม่แน่ใจว่ามันเป็นค่าที่แท้จริงหรือไม่ (สิบหลักสุดท้ายเป็นศูนย์) ฉันเดาว่ามูลค่าที่แท้จริงหายไป ขอบคุณ!
hgulyan

2
@hgulyan - ตัวเลขสิบหลักสุดท้ายเป็นศูนย์เพราะนั่นคือพารามิเตอร์สุดท้ายสำหรับในStrฟังก์ชัน จำนวนหลักหลังจุดทศนิยม คุณอ่านลิงค์ที่ฉันโพสต์หรือไม่? เปลี่ยนศูนย์เป็น 10 Select LTRIM(Str(float_field, 38, 10))
codingbadger

4
ฉันหวังว่าจะมีคำเตือนใน SSMS "เดี๋ยวก่อนเมื่อคุณแปลงช่องโทรศัพท์ลอยที่ผิดพลาดเป็นข้อความเตรียมพร้อมที่จะรับหมายเลขโทรศัพท์ที่ดีพร้อมสัญลักษณ์ทางวิทยาศาสตร์! เราไม่ฉลาดพอที่จะ ltrim (str) ก่อน" ...
pkExec

42

บิตแบบสอบถามเดียวที่ฉันพบว่าส่งคืนหมายเลขเดิมที่แน่นอนคือ

CONVERT (VARCHAR(50), float_field,128)

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

วิธีแก้ปัญหาอื่น ๆ ข้างต้นบางครั้งจะปัดเศษหรือเพิ่มตัวเลขในตอนท้าย

UPDATE : ตามความคิดเห็นด้านล่างและสิ่งที่ฉันเห็นใน https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

ควรใช้ใน SQL Server เวอร์ชันใหม่ (ฐานข้อมูล Azure SQL และเริ่มต้นใน SQL Server 2016 RC3)


2
+1 สำหรับ @adinas ค่าลอยจะถูกแปลงเป็นมัน แต่มีข้อยกเว้นของมูลค่าลอยถูกแปลงเป็น0 0.0E0ฉันต้องการแปลงฟิลด์โฟลตvarcharเป็นเพราะฉันต้องการแสดงNAเมื่อใดNULLและ0ตามที่เป็นอยู่ ฉันทำได้โดยการเพิ่มCASEคำสั่งในแบบสอบถามด้านล่าง 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
ตามเอกสารใน Microsoft - msdn.microsoft.com/en-us/library/ms187928.aspxไวยากรณ์ 128 ถูกรวมไว้ด้วยเหตุผลเดิมและอาจถูกยกเลิกในเวอร์ชันในอนาคต
Mike Turner

1
128 เลิกใช้งานแล้ว แต่ดูเหมือนว่า 3 จะแทนที่ใน SQL Server รุ่นล่าสุด
user3524983

13

นี่เป็นวิธีแก้ปัญหาที่ฉันใช้ใน sqlserver 2012 (เนื่องจากคำแนะนำอื่น ๆ ทั้งหมดมีข้อเสียของการตัดทอนส่วนที่เป็นเศษส่วนหรือข้อเสียเปรียบอื่น ๆ )

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

เอาท์พุท:

1000000000.1234

สิ่งนี้มีข้อดีเพิ่มเติม (ในกรณีของฉัน) ในการทำให้ตัวคั่นหลายพันตัวและการแปลเป็นภาษาท้องถิ่นได้ง่าย:

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

เอาท์พุท:

1.000.000.000,1234

3

ขอบคุณหัวข้อที่เป็นประโยชน์

ถ้าคุณต้องการเช่นฉันลบศูนย์นำคุณสามารถใช้สิ่งนั้น:

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

2

floatมีค่าสูงสุดเท่านั้น ความแม่นยำ 15 หลัก ตัวเลขหลังจากตำแหน่งที่ 15 จึงเป็นแบบสุ่มและการแปลงเป็น bigint (สูงสุด 19 หลัก) หรือทศนิยมไม่ได้ช่วยคุณ


ฉันไม่เข้าใจ ค่าฟิลด์คือ 2.2000012095022E + 26 ทางออกคืออะไร? ไม่มีเลยเหรอ?
hgulyan

คุณไม่สามารถรับตัวเลขได้มากขึ้นโดยการแปลงเป็นสตริงมากกว่าที่มีตัวเลขเก็บไว้ในค่าดั้งเดิม
devio

ฉันสูญเสียตัวเลขหลังจากอันดับที่ 15?
hgulyan

มีปัญหาบางอย่างกับข้อมูล ฉันแค่ต้องอัปเดตค่านั้นด้วยตัวเลข 15 หลัก ฉันจะยอมรับคำตอบของคุณเพราะมันอธิบายถึงปัญหาหลักที่ฉันพบกับข้อมูลนี้ ขอบคุณ.
hgulyan

2

สิ่งนี้สามารถช่วยได้โดยไม่ต้องปัดเศษ

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

แปลงเป็นสิ่งintegerแรกแล้วเป็นstring:

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

การดำเนินการนี้จะลบตัวเลขหลังจุดทศนิยมถ้ามี ดังนั้นวิธีนี้จึงไม่ถูกต้อง
RushabhG


1

หากคุณใช้ฟังก์ชัน CLR คุณสามารถแปลงโฟลตเป็นสตริงที่ดูเหมือนโฟลตโดยไม่ต้องมี 0 พิเศษทั้งหมดที่ท้าย

ฟังก์ชัน 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; }
}

.

ตัวอย่าง

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

.

เอาท์พุต

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

.

ข้อแม้

สตริงที่แปลงแล้วทั้งหมดจะถูกตัดทอนที่ทศนิยม 18 ตำแหน่งและไม่มีศูนย์ต่อท้าย ความแม่นยำ 18 หลักไม่ใช่ปัญหาสำหรับเรา และ 100% ของหมายเลข FP ของเรา (ใกล้เคียงกับ 100,000 ค่า) จะมีลักษณะเหมือนกันกับค่าสตริงเช่นเดียวกับที่ทำในฐานข้อมูลเป็นหมายเลข FP


0

การตอบสนองของ Axel ที่ปรับเปลี่ยนเล็กน้อยเนื่องจากในบางกรณีจะให้ผลลัพธ์ที่ไม่พึงปรารถนา

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

จากเอกสาร REPLACE () :

ส่งคืน nvarchar หากหนึ่งในอาร์กิวเมนต์อินพุตเป็นชนิดข้อมูล nvarchar มิฉะนั้น REPLACE จะส่งคืน varchar
ส่งคืนค่า NULL หากอาร์กิวเมนต์ใดอาร์กิวเมนต์เป็น NULL

การทดสอบ:
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

เลือก
cast (แทนที่ (แปลง (ทศนิยม (15,2), acs_daily_debit), ". ',', ') เป็น varchar (20))

จาก acs_balance_details


0

ขึ้นอยู่กับคำตอบของโมเลกุล:

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

ฉันเพิ่งเจอสถานการณ์ที่คล้ายกันและรู้สึกประหลาดใจกับปัญหาการปัดเศษของ 'ตัวเลขขนาดใหญ่มาก' ที่นำเสนอภายใน SSMS v17.9.1 / SQL 2017

ฉันไม่ได้แนะนำว่าฉันมีวิธีแก้ปัญหา แต่ฉันสังเกตว่าFORMAT นำเสนอตัวเลขที่ดูเหมือนถูกต้อง ฉันไม่สามารถบอกเป็นนัยได้ว่าสิ่งนี้ช่วยลดปัญหาการปัดเศษเพิ่มเติมหรือมีประโยชน์ในฟังก์ชันทางคณิตศาสตร์ที่ซับซ้อน

T SQL Code ที่ให้มาซึ่งควรแสดงให้เห็นอย่างชัดเจนถึงข้อสังเกตของฉันในขณะที่ให้ผู้อื่นทดสอบโค้ดและแนวคิดของพวกเขาหากจำเป็น

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

เป็นวิธีที่ดีที่สุดดังนั้นคุณจึงไม่ต้องเพิ่ม.0000และตัวเลขใด ๆ ต่อท้ายค่า

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.