У меня есть столбец, DECIMAL(9,6)
т.е. он поддерживает такие значения, как 999,123456.
Но когда я вставляю данные типа 123,4567, они становятся 123,456700
Как убрать эти нули?
sql
tsql
sql-server-2008
formatting
decimal
Абатищев
источник
источник
Ответы:
A
decimal(9,6)
хранит 6 цифр справа от запятой. Отображать ли завершающие нули или нет - это решение форматирования, обычно реализуемое на стороне клиента.Но поскольку SSMS форматирует
float
без конечных нулей, вы можете удалить конечные нули, приведяdecimal
кfloat
:select cast(123.4567 as DECIMAL(9,6)) , cast(cast(123.4567 as DECIMAL(9,6)) as float)
печатает:
(Мой десятичный разделитель - это запятая, но SSMS форматирует десятичное число с точкой. Очевидно, это известная проблема .)
источник
Вы можете использовать
FORMAT()
функцию (SqlAzure и Sql Server 2012+):SELECT FORMAT(CAST(15.12 AS DECIMAL(9,6)), 'g18') -- '15.12' SELECT FORMAT(CAST(0.0001575 AS DECIMAL(9,6)), 'g10') -- '0.000158' SELECT FORMAT(CAST(2.0 AS DECIMAL(9,6)), 'g15') -- '2'
Будьте осторожны при использовании с FLOAT (или REAL): не используйте
g17
или больше (g8
или больше с REAL), потому что ограниченная точность машинного представления вызывает нежелательные эффекты:SELECT FORMAT(CAST(15.12 AS FLOAT), 'g17') -- '15.119999999999999' SELECT FORMAT(CAST(0.9 AS REAL), 'g8') -- '0.89999998' SELECT FORMAT(CAST(0.9 AS REAL), 'g7') -- '0.9'
Кроме того, обратите внимание, что согласно документации :
Также работает в SqlAzure.
источник
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
источник
Я не хотел приводить к типу float из-за того, что в моей десятичной дроби может быть больше цифр, чем может представлять float
FORMAT
при использовании со стандартной строкой формата .net 'g8' возвращал научную нотацию в случаях очень маленьких десятичных знаков (например, 1e-08), что также было неподходящимИспользование строки настраиваемого формата ( https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings ) позволило мне добиться того, чего я хотел:
DECLARE @n DECIMAL(9,6) =1.23; SELECT @n --> 1.230000 SELECT FORMAT(@n, '0.######') --> 1.23
Если вы хотите, чтобы в вашем номере был хотя бы один конечный ноль, чтобы 2.0 не превратилось в 2, используйте строку формата, например
0.0#####
Десятичная точка локализована, поэтому в культурах, в которых в качестве десятичного разделителя используется запятая, будет выводиться запятая, где расширение. является
Конечно, это обескураживающая практика, когда уровень данных выполняет форматирование (но в моем случае другого слоя нет; пользователь буквально запускает хранимую процедуру и отправляет результат по электронной почте: /)
источник
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
печатает:
источник
должен это сделать.
источник
Попробуй это :
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Дает 20,55
источник
0.000
стал.
. вот исправлениеSELECT REPLACE(RTRIM(REPLACE(20.5500, "0", " ")), " ", "0")
для обрезки только конечных нулейУ меня была аналогичная проблема, но мне также требовалось удалить десятичную точку, где десятичная дробь не присутствовала, вот мое решение, которое разбивает десятичную дробь на ее компоненты и основывает количество символов, которое он берет из строки десятичной точки, на длине компонент фракции (без использования CASE). Чтобы сделать ситуацию еще более интересной, мое число хранилось как число с плавающей запятой без десятичных знаков.
DECLARE @MyNum FLOAT SET @MyNum = 700000 SELECT CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),2) AS VARCHAR(10)) + SUBSTRING('.',1,LEN(REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0'))) + REPLACE(RTRIM(REPLACE(CAST(PARSENAME(CONVERT(NUMERIC(15,2),@MyNum/10000),1) AS VARCHAR(2)),'0',' ')),' ','0')
Я знаю, что результат болезненный, но я добился этого, благодаря приведенным выше ответам.
источник
Лучший способ - НЕ преобразовывать в FLOAT или MONEY перед преобразованием из-за вероятности потери точности. Таким образом, безопасные способы могут быть примерно такими:
CREATE FUNCTION [dbo].[fn_ConvertToString] ( @value sql_variant ) RETURNS varchar(max) AS BEGIN declare @x varchar(max) set @x= reverse(replace(ltrim(reverse(replace(convert(varchar(max) , @value),'0',' '))),' ',0)) --remove "unneeded "dot" if any set @x = Replace(RTRIM(Replace(@x,'.',' ')),' ' ,'.') return @x END
где @value может быть любым десятичным числом (x, y)
источник
sp_
для хранимых процедур,fn_
для функций,tbl
для таблиц и т. д. на ... это не требование, но это лучший способ организации наших баз данных.У меня была аналогичная проблема, мне нужно было обрезать конечные нули из чисел вроде
xx0000,x00000,xxx000
Я использовал:
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
Код - это имя поля, номер которого нужно обрезать. Надеюсь, это поможет кому-то другому.
источник
Другой вариант...
Я не знаю, насколько это эффективно, но похоже, что он работает и не проходит через float:
select replace(rtrim(replace( replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0') , '.', ' ')), ' ', '.')
Средняя линия удаляет конечные пробелы, две внешние удаляют точку, если нет десятичных цифр.
источник
Мне нужно было удалить конечные нули в моих десятичных числах, чтобы я мог вывести строку определенной длины только с ведущими нулями
(например, мне нужно было вывести 14 символов, чтобы 142.023400 стало 000000142.0234),
Я использовал
parsename
,reverse
иcast
as int
для удаления конечных нулей:SELECT PARSENAME(2.5500,2) + '.' + REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))
(Чтобы затем получить мои ведущие нули, я мог бы воспроизвести правильное количество нулей в зависимости от длины вышеупомянутого и объединить его с лицевой стороной вышеупомянутого)
Надеюсь, это кому-нибудь поможет.
источник
в TSQL можно убрать начальные и конечные нули
Преобразуйте его в строку, используя функцию STR TSQL, если не строку, Затем
Удалите начальные и конечные нули
SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
Больше информации на форуме .
источник
REPLACE(RTRIM(REPLACE(REPLACE(RTRIM(REPLACE(X,'0',' ')),' ','0'),'.',' ')),' ','.')
Как насчет этого? Предполагая, что данные поступают в вашу функцию как @thisData:
BEGIN DECLARE @thisText VARCHAR(255) SET @thisText = REPLACE(RTRIM(REPLACE(@thisData, '0', ' ')), ' ', '0') IF SUBSTRING(@thisText, LEN(@thisText), 1) = '.' RETURN STUFF(@thisText, LEN(@thisText), 1, '') RETURN @thisText END
источник
case when left(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.' then '0' else '' end + replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0') + case when right(replace(ltrim(rtrim(replace(str(XXX, 38, 10), '0', ' '))), ' ', '0'), 1) = '.' then '0' else '' end
источник
Я понимаю, что это старый пост, но хотел бы предоставить SQL, который я придумал
DECLARE @value DECIMAL(23,3) set @value = 1.2000 select @value original_val, SUBSTRING( CAST( @value as VARCHAR(100)), 0, PATINDEX('%.%',CAST(@value as VARCHAR(100))) ) + CASE WHEN ROUND( REVERSE( SUBSTRING( CAST(@value as VARCHAR(100)), PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1, LEN(CAST(@value as VARCHAR(100))) ) ) ,1) > 0 THEN '.' + REVERSE(ROUND(REVERSE(SUBSTRING( CAST(@value as VARCHAR(100)), PATINDEX('%.%',CAST(@value as VARCHAR(100)))+1, LEN(CAST(@value as VARCHAR(100))) ) ),1)) ELSE '' END AS modified_val
источник
попробуй это.
select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
источник
Самый простой способ - преобразовать значение как FLOAT, а затем в строковый тип данных.
источник
Попробуй это:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
источник
Я знаю, что этот поток очень старый, но для тех, кто не использует SQL Server 2012 или более поздней версии или не может использовать функцию FORMAT по какой-либо причине, работает следующее.
Кроме того, многие решения не работали, если число было меньше 1 (например, 0,01230000).
Обратите внимание, что следующее не работает с отрицательными числами.
DECLARE @num decimal(28,14) = 10.012345000 SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0') set @num = 0.0123450000 SELECT PARSENAME(@num,2) + REPLACE(RTRIM(LTRIM(REPLACE(@num-PARSENAME(@num,2),'0',' '))),' ','0')
Возвращает 10,012345 и 0,012345 соответственно.
источник
Попробуй это:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)
источник
999999
, OP просит удалить конечные нули.Столбец DECIMAL (9,6) преобразуется в число с плавающей запятой без потери точности, поэтому CAST (... AS float) поможет.
@HLGEM: сказать, что float - плохой выбор для хранения чисел, а «Никогда не использовать float» неверно - вам просто нужно знать свои числа, например, измерения температуры будут хорошо проходить как поплавки.
@abatishchev и @japongskie: префиксы перед сохраненными процедурами и функциями SQL по-прежнему являются хорошей идеей, если не требуются; упомянутые вами ссылки только инструктируют не использовать префикс «sp_» для хранимых процедур, которые вы не должны использовать, другие префиксы подходят, например, «usp_» или «spBob_»
Ссылка: «Все целые числа с 6 или менее значащими десятичными знаками могут быть преобразованы в значение с плавающей запятой IEEE 754 без потери точности»: https://en.wikipedia.org/wiki/Single-precision_floating-point_format
источник