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


11

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

Наприклад, зробимо простий поділ як 1234/1233. Калькулятор видасть 100081103000811. Але коли я роблю це на 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
  • жити зі втратою точності
  • використовувати якнайкраще поплавок і жити з 15 значущими фігурами

По-перше, дивіться це на SO /programming/423925/t-sql-decimal-division-accuracy/424052#424052


1

Не впевнений, чи це допомагає, але для мене мій стовпчик таблиці темп був встановлений у десятковій мірі, я передавав перетворення (десятковий (15,2), 0,65) із вставки в temp_table. Це було автоматичне округлення, я змінив тип стовпця на десятковий (16,2), щоб відповідати тому, що передається. Зараз таблиця зберігає 0,65.


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

Сподіваюсь, це допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.