Автоматическое десятичное округление

11

Вопрос относительно прост. Мне нужно вычислить 3 столбца, где средние результаты - огромные десятичные дроби, и я сталкиваюсь с проблемой на ранних этапах, когда SQL Server в основном округляет десятичные числа независимо от каких-либо приведений / преобразований.

Например, давайте сделаем простое деление как 1234/1233. Калькулятор выдаст 1 00081103000811. Но когда я делаю это на SQL Server, мы получаем следующее:

-- Result: rounded at 1.000811000... with trailing zeroes up until the 37 precision
SELECT CAST(CAST(1234 AS DEC(38,34))/CAST(1233 AS DEC(38,34)) AS DEC(38,37))

-- Result: rounded at 1.000811
SELECT CONVERT(DECIMAL(38,32), 1234)/CONVERT(DECIMAL(38,32),1233)

-- Correct result at 1,00081103000811
-- But this requires the zeroes to be put in manually when you don't
-- even know the precision of the end result
SELECT 1234.0/1233.00000000000000

Почему происходит автоматическое округление? И как лучше всего рассчитать безумно длинные десятичные значения, когда вы не можете быть уверены, насколько большим будет число (часть int или dec), поскольку таблица может содержать различные значения?

Спасибо!

Кан
источник

Ответы:

17

ТЛ; др

Не делайте вычисления на языке SQL

дольше

Масштаб и точность результата хорошо определены здесь, в MSDN . Это не интуитивно понятно. Однако, проще говоря, точность теряется, когда входные весы высоки, потому что весы результата должны быть уменьшены до 38 с соответствующим падением точности.

Чтобы подтвердить вещи

  • Ваш дополнительный CAST в первом примере просто добавляет нули
  • Усечение происходит согласно моей ссылке MSDN (2-й пример)
  • В третьем примере с константами подразумеваются десятичные значения, которых достаточно (5,1) и 18,14).
    Это означает, что масштаб и точность результата не имеют усечения (см. Удар)

Подробнее о 1-м и 3-м случаях.

Шкала результата для подразделения max(6, s1 + p2 + 1):

  • Первый пример, это 77, которое упало до 38. Точность снижается аналогичным образом, с минимумом 6 (см. Это )
  • Третий пример, это 24, поэтому точность не нуждается в настройке

У вас есть несколько вариантов

  • рассчитать в коде клиента, например .net
  • использовать функции CLR для расчетов .net
  • жить с потерей точности
  • используйте float и живите с 15 значащими фигурами как лучше

Наконец, посмотрите это на SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052

ГБН
источник
1

Не уверен, что это поможет, но для меня столбец временной таблицы был установлен в десятичном формате, я передавал преобразование (десятичное (15,2), 0,65) из вставки в temp_table. Это было автоматическое округление, я изменил тип столбца на десятичный (16,2), чтобы соответствовать тому, что было передано. Таблица сейчас хранит 0,65.

natur3
источник
1

Я должен был сделать работу вокруг. Вот что я сделал:

-----------------------------------
DECLARE @DENIED INT  = 33443
DECLARE @PAID INT = 148353
DECLARE @PCT Decimal (6,2)

SET @PCT = (@DENIED * 100.00 / @PAID)  -- Instead of dividing by 100, I included decimals

SELECT
@DENIED AS DEN
,@PAID AS PAID
,@PCT AS PCT

Результаты:

DEN PAID    PCT
-----   ----    -----
33443   148353  22.54   -- Instead of 22.00

Надеюсь это поможет.

Маной С
источник