Усеченные (не круглые) десятичные знаки в SQL Server


194

Я пытаюсь определить лучший способ обрезать или отбрасывать лишние десятичные разряды в SQL без округления. Например:

declare @value decimal(18,2)

set @value = 123.456

Это автоматически круглый @valueбыть 123.46, это хорошо в большинстве случаев. Однако для этого проекта мне это не нужно. Есть ли простой способ обрезать десятичные дроби, которые мне не нужны? Я знаю, что могу использовать left()функцию и преобразовать обратно в десятичную. Есть ли другие способы?

Ответы:


188
select round(123.456, 2, 1)

28
Ответ должен объяснить, каковы параметры функции
Тайлер

9
SQL ROUND (число, десятичные дроби, операция): операция -> Если 0, округляет результат до десятичного числа. Если другое значение, кроме 0, оно усекает результат до количества десятичных знаков. По умолчанию 0
Midhun Darvin

Вы спасатель жизни, у меня было количество, чтобы показать последние две цифры только "1.9991666", однако оно всегда округляется до 2, независимо от того, что я использую, с этим я могу достичь чего-то вроде этого - выберите FORMAT (round (1.9991666) , 2, 1), 'N2') AS 'Rate', Спасибо, приятель
Паук

269
ROUND ( 123.456 , 2 , 1 )

Когда третий параметр ! = 0, он усекает, а не округляет

http://msdn.microsoft.com/en-us/library/ms175003(SQL.90).aspx

Синтаксис

ROUND ( numeric_expression , length [ ,function ] )

аргументы

  • numeric_expression Является выражением категории точных числовых или приблизительных числовых типов данных, за исключением типа битовых данных.

  • length Точность, до которой округляется числовое выражение. длина должна быть выражением типа tinyint, smallint или int. Когда длина является положительным числом, numeric_expression округляется до числа десятичных разрядов, указанного в length. Когда длина является отрицательным числом, numeric_expression округляется с левой стороны десятичной точки, как указано в length.

  • function Тип операции для выполнения. функция должна быть tinyint, smallint или int. Когда функция опущена или имеет значение 0 (по умолчанию), числовое выражение округляется. Если указано значение, отличное от 0, выражение numeric_expression усекается.

Кто-нибудь знает, какие значения для аргумента функции соответствуют tinyint, smallint и int? Microsoft исключила эту часть из своей документации и нигде не может найти ответ. msdn.microsoft.com/en-us/library/ms175003(SQL.90).aspx
Дейв

MS SQL SERVER округляет числа немного иначе, чем IQ. Чтобы исправить, используйте функцию round (x, y, z), как этот раунд (val1 / val2,4,1)
Уоррен


13

Вот способ, которым я смог усечь, а не округлять:

select 100.0019-(100.0019%.001)

возвращает 100.0010

И твой пример:

select 123.456-(123.456%.001)

возвращает 123.450

Теперь, если вы хотите избавиться от конечного нуля, просто приведите его:

select cast((123.456-(123.456%.001)) as decimal (18,2))

возвращает 123.45


10

На самом деле, каким бы ни был третий параметр, 0 или 1 или 2, он не будет округлять ваше значение.

CAST(ROUND(10.0055,2,0) AS NUMERIC(10,2))

Я не понимаю этот ответ. Результатом SQL является 10.01, что является правильным округлением 10.0055 до двух десятичных знаков. Если последний параметр не равен 0, значение усекается (до 2 десятичных разрядов) до 10,00.
8128

7

Round имеет необязательный параметр

Select round(123.456, 2, 1)  will = 123.45
Select round(123.456, 2, 0)  will = 123.46

3
Выбор раунда (123,456, 2, 1) будет = 123,450
Бикрам

4
Я не понимаю, почему это вызывает голоса. Выше даст вам 123,450 и 123,460 соответственно.
ремикарем

7

Вы хотите десятичную или нет?

Если нет, используйте

select ceiling(@value),floor(@value)

Если вы делаете это с 0, тогда сделайте раунд:

select round(@value,2)

1
Извините, если мне неясно, мне нужно сохранить десятичные разряды, просто отбросить те, которые мне не нужны. Например, вместо 123.456 в моем примере, приведенном выше, конвертируется в 123.46 ... Я хочу отбросить третий десятичный знак и сделать его 123.45.
Райан Истабрук

6

Еще одно усечение без округления решения и примера.

    Convert 71.950005666 to a single decimal place number (71.9)
    1) 71.950005666 * 10.0 = 719.50005666
    2) Floor(719.50005666) = 719.0
    3) 719.0 / 10.0 = 71.9

    select Floor(71.950005666 * 10.0) / 10.0

2
+1, для Floor()которого и есть путь к десятичному числу без округления. Жаль, что у Floor () нет второго параметра, который бы указывал на какую позицию. Но я думаю, что * 10) / 10 действительно работает в этом направлении.
Дероби



1

Другой способ это ODBC TRUNCATEфункция:

DECLARE @value DECIMAL(18,3) =123.456;

SELECT @value AS val, {fn TRUNCATE(@value, 2)} AS result

LiveDemo

Вывод:

╔═════════╦═════════╗
   val    result  
╠═════════╬═════════╣
 123,456  123,450 
╚═════════╩═════════╝

Замечание:

Я рекомендую использовать встроенную ROUNDфункцию с третьим параметром, установленным в 1.


1
Скалярная функция ODBC - другая альтернатива!
Арулмужи

1

Я знаю, что уже довольно поздно, но я не вижу в этом ответа и уже давно использую этот трюк.

Просто вычтите .005 из вашего значения и используйте Round (@ num, 2).

Ваш пример:

declare @num decimal(9,5) = 123.456

select round(@num-.005,2)

возвращает 123.45

Он автоматически отрегулирует округление до нужного значения, которое вы ищете.

Кстати, вы воссоздаете программу из фильма Office Space?


0

Пожалуйста, попробуйте использовать этот код для преобразования 3 десятичных значений после точки в 2 десятичных знака:

declare @val decimal (8, 2)
select @val = 123.456
select @val =  @val

select @val

Выход 123.46


1) 3-я строка совершенно не нужна 2) он явно сказал, что не хочет округлять число, но обрезает его (результат должен быть 123,45)
Дамиан Пабло Гонсалес

0

Я думаю, что вы хотите только десятичное значение, в этом случае вы можете использовать следующее:

declare @val decimal (8, 3)
SET @val = 123.456

SELECT @val - ROUND(@val,0,1)

0

Я знаю, что этот вопрос действительно старый, но никто не использовал подстроки для округления. Это как преимущество возможности округлять действительно длинные числа (предел вашей строки на сервере SQL, который обычно составляет 8000 символов):

SUBSTRING('123.456', 1, CHARINDEX('.', '123.456') + 2)

0

Я думаю, что мы можем пойти намного проще с более простым примером решения, найденным в Hackerrank:

Постановка проблемы: Запросите наибольшее значение северных широт (LAT_N) у STATION, которое меньше 137.2345. Усечь свой ответ до 4 десятичных знаков.

SELECT TRUNCATE(MAX(LAT_N),4)
FROM STATION
WHERE LAT_N < 137.23453;

Решение выше дает вам представление о том, как просто сделать значение ограниченным 4 десятичными знаками. Если вы хотите уменьшить или увеличить цифры после десятичной дроби, просто измените 4 на любое другое.



-5
select convert(int,@value)

1
Это не то, что хотел ОП. Ему все еще нужны десятичные знаки, но он хочет удалить их (усечение), а не округлять их. IE 123.456 -> 123.45 НЕ 123.456 -> 12.46 и НЕ 123.456 -> 123
Джон
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.