Подтвердить что ты не робот

Удалить конечные нули из десятичного числа в SQL Server

У меня есть столбец DECIMAL(9,6), т.е. он поддерживает такие значения, как 999,123456.

Но когда я вставляю данные, например, 123,4567, он становится 123,456700

Как удалить эти нули?

4b9b3361

Ответ 1

Если вы не хотите преобразовать его в строку, вы не сможете. Вам нужно сделать это на уровне презентации.

Ответ 2

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 форматы десятичные с точкой. По-видимому, известная проблема.)

Ответ 3

Вы можете использовать функцию 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.

Ответ 4

SELECT CONVERT(DOUBLE PRECISION, [ColumnName])

Ответ 5

SELECT REVERSE(ROUND(REVERSE(2.5500),1))

печатает:

2.55

Ответ 6

Cast(20.5500 as Decimal(6,2))

должен это сделать.

Ответ 7

У меня была аналогичная проблема, но также требовалось удалить десятичную точку, в которой не было десятичной дроби, вот мое решение, которое разбивает десятичную дробь на ее компоненты и основывает количество символов, которые она принимает из десятичной точки в строке длина компонента фракции (без использования 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') 

Результат болезнен, я знаю, но я попал туда, с большой помощью от ответов выше.

Ответ 8

Мне нужно было удалить конечные нули на десятичных запятых, чтобы я мог выводить строку определенной длины только с ведущими нулями

(например, мне нужно было вывести 14 символов, чтобы 142.023400 стал 000000142.0234),

Я использовал parsename, reverse и cast as int для удаления конечных нулей:

SELECT
    PARSENAME(2.5500,2)
    + '.'
    + REVERSE(CAST(REVERSE(PARSENAME(2.5500,1)) as int))

(Чтобы затем получить мои ведущие нули, я мог бы реплицировать правильное количество нулей на основе длины вышеописанного и объединить это в начало выше)

Надеюсь, это поможет кому-то.

Ответ 9

можно удалить ведущие и конечные нули в TSQL

  • Преобразуйте его в строку, используя функцию STR TSQL, если не строку, Затем

  • Удалите начальные и конечные нули

    SELECT REPLACE(RTRIM(LTRIM(REPLACE(AccNo,'0',' '))),' ','0') AccNo FROM @BankAccount
    
  • Дополнительная информация о форуме.

Ответ 10

Попробуйте следующее:

SELECT REPLACE(TRIM(REPLACE(20.5500, "0", " ")), " ", "0")

Дает 20.55

Ответ 11

Лучший способ НЕ преобразовать в 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)

Ответ 12

Другая опция...

Я не знаю, насколько это эффективно, но, похоже, работает и не идет через float:

select replace(rtrim(replace(
       replace(rtrim(replace(cast(@value as varchar(40)), '0', ' ')), ' ', '0')
       , '.', ' ')), ' ', '.')

Средняя строка удаляет конечные пробелы, внешние два удаляют точку, если нет десятичных цифр

Ответ 13

Как насчет этого? Предполагая, что данные поступают в вашу функцию как @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

Ответ 14

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

Ответ 15

Я понимаю, что это старый пост, но хотел бы предоставить 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

Ответ 16

Я знаю, что этот поток очень старый, но для тех, кто не использует 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 соответственно.

Ответ 17

попробуйте это.

select CAST(123.456700 as float),cast(cast(123.4567 as DECIMAL(9,6)) as float)

Ответ 18

Самый простой способ - CAST значение как FLOAT, а затем - строковый тип данных.

CAST(CAST(123.456000 AS FLOAT) AS VARCHAR(100))

Ответ 19

У меня была аналогичная проблема, необходимая для обрезания конечных нулей из чисел вроде xx0000,x00000,xxx000

Я использовал:

select LEFT(code,LEN(code)+1 - PATINDEX('%[1-Z]%',REVERSE(code))) from Tablename

Код - это имя поля с номером, подлежащим обрезке. Надеюсь, это поможет кому-то еще.

Ответ 20

Столбец 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

Ответ 21

Попробуйте следующее:

select Cast( Cast( (ROUND( 35.457514 , 2) *100) as Int) as float ) /100

Ответ 22

Попробуйте следующее:

select isnull(cast(floor(replace(rtrim(ltrim('999,999.0000')),',','')) as int),0)