У меня есть столбец DECIMAL(9,6)
, т.е. он поддерживает такие значения, как 999,123456.
Но когда я вставляю данные, например, 123,4567, он становится 123,456700
Как удалить эти нули?
У меня есть столбец DECIMAL(9,6)
, т.е. он поддерживает такие значения, как 999,123456.
Но когда я вставляю данные, например, 123,4567, он становится 123,456700
Как удалить эти нули?
Если вы не хотите преобразовать его в строку, вы не сможете. Вам нужно сделать это на уровне презентации.
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)
печатает:
123.456700 123,4567
(Мой десятичный разделитель - это запятая, но 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'
Кроме того, обратите внимание, что в соответствии с документация:
FORMAT полагается на присутствие .NET Framework Common Language Время выполнения (CLR). Эта функция не будет удалена, поскольку она зависит от наличие CLR. Удаление функции, требующей CLR приведет к ошибке на удаленном сервере.
Работает также в SqlAzure.
SELECT CONVERT(DOUBLE PRECISION, [ColumnName])
SELECT REVERSE(ROUND(REVERSE(2.5500),1))
печатает:
2.55
Cast(20.5500 as Decimal(6,2))
должен это сделать.
У меня была аналогичная проблема, но также требовалось удалить десятичную точку, в которой не было десятичной дроби, вот мое решение, которое разбивает десятичную дробь на ее компоненты и основывает количество символов, которые она принимает из десятичной точки в строке длина компонента фракции (без использования CASE). Чтобы сделать еще более интересным, мой номер хранился как float без десятичных знаков.
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')
Результат болезнен, я знаю, но я попал туда, с большой помощью от ответов выше.
Мне нужно было удалить конечные нули на десятичных запятых, чтобы я мог выводить строку определенной длины только с ведущими нулями
(например, мне нужно было вывести 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
Дополнительная информация о форуме.
Попробуйте следующее:
SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")
Дает 20.55
Лучший способ НЕ преобразовать в FLOAT или ДЕНЬГИ до преобразования из-за вероятности потери точности. Таким образом, безопасные способы могут быть примерно такими:
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)
Другая опция...
Я не знаю, насколько это эффективно, но, похоже, работает и не идет через float:
select replace(rtrim(replace(
replace(rtrim(replace(cast(@value as varchar(40)), '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
Я знаю, что этот поток очень старый, но для тех, кто не использует 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 CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)
Самый простой способ - CAST значение как FLOAT, а затем - строковый тип данных.
CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))
У меня была аналогичная проблема, необходимая для обрезания конечных нулей из чисел вроде xx0000,x00000,xxx000
Я использовал:
select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename
Код - это имя поля с номером, подлежащим обрезке. Надеюсь, это поможет кому-то еще.
Столбец DECIMAL (9,6) преобразуется в float без потери точности, поэтому CAST (... AS float) выполнит трюк.
@HLGEM: говоря, что float - плохой выбор для хранения чисел, и "Never use float" неверен - вам просто нужно знать ваши цифры, например. измерения температуры будут хорошо выглядеть как плавающие.
@abatishchev и @japongskie: префиксы перед хранимыми в SQL процессами и функциями по-прежнему являются хорошей идеей, если это не требуется; ссылки, которые вы упомянули, инструктируют не использовать префикс "sp_" для хранимых процедур, которые вы не должны использовать, другие префиксы являются точными, например. "usp_" или "spBob _"
Ссылка: "Все целые числа с 6 или менее значащими десятичными цифрами могут быть преобразованы в значение с плавающей запятой IEEE 754 без потери точности": https://en.wikipedia.org/wiki/Single-precision_floating-point_format
Попробуйте следующее:
select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100
Попробуйте следующее:
select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)