Як конвертувати float у varchar у SQL Server


130

У мене є поплавковий стовпчик з номерами різної довжини і я намагаюся перетворити їх у варчар.

Деякі значення перевищують bigint max size, тому я не можу зробити щось подібне

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

Я намагався використовувати десятковий, але цифри не однакового розміру, тому це теж не допомагає

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

Будь-яка допомога вдячна.

ОНОВЛЕННЯ:

Значення зразка - 2.2000012095022E + 26 .


cast(float_field as varchar(max))інакше у мене не виникає питання
Денис Валєєв

5
значення для вашого акторського складу - 2,2e + 026. Напевно, у вас не
виникає сумнівів

Відповіді:


246

Спробуйте скористатися 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, здається, працює, але так само, як і десятковий, тому я не впевнений, чи справжнє це значення (останні десять цифр дорівнюють нулю). Я здогадуюсь, що реальна цінність була втрачена. Дякую!
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

Інші рішення, наведені вище, іноді будуть округленими або додавати цифри в кінці

ОНОВЛЕННЯ : Відповідно до коментарів нижче та того, що я бачу на https://msdn.microsoft.com/en-us/library/ms187928.aspx :

CONVERT (VARCHAR(50), float_field,3)

Потрібно використовувати в нових версіях сервера SQL (база даних Azure SQL і починаючи з RC3 SQL Server 2016)


2
+1 для @adinas, значення float перетворюється як би, але за винятком 0значення float, перетвореного як 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 включений із застарілих причин і може бути застарілим у наступній версії
Майк Тернер

1
128 застаріло, але 3, здається, замінили його в останніх випусках SQL Server.
користувач3524983

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

не можна отримати більше цифр шляхом перетворення в рядок, ніж цифри, збережені в початковому значенні.
девіо

Отже, я втратив цифри після 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

2

Спробуйте це, повинно працювати:

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

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

.

Caveat

Усі конвертовані рядки обрізані в 18 десяткових знаках, і немає ніяких кінцевих нулів. 18 цифр точності для нас не є проблемою. І 100% наших FP-номерів (близько 100 000 значень) виглядають ідентичними, як і рядкові значення, як і в базі даних, як номери FP.


0

Трохи модифікувавши відповідь Акселя, оскільки це для певних випадків призведе до небажаних результатів.

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

Виберіть
команду (замінити (перетворити (десяткове (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, який повинен чітко демонструвати мої спостереження, дозволяючи іншим перевірити свій код та ідеї, якщо виникне потреба.

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і жодної цифри в кінці значення.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.