자동 10 진수 반올림 문제


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

tl; dr

SQL 언어로 계산하지 마십시오

더 길게

결과 규모와 정밀도는 여기 MSDN에 잘 정의되어 있습니다 . 정말 직관적이지 않습니다. 그러나 간단히 말해서, 입력 스케일이 높으면 결과 스케일을 일치하는 정밀도 드롭으로 38로 떨어 뜨려야하기 때문에 정밀도가 손실됩니다.

확인하기 위해

  • 첫 번째 예에서 추가 CAST는 단순히 0을 추가합니다.
  • 잘림은 MSDN 링크에 따라 발생합니다 (두 번째 예).
  • 상수가 포함 된 세 번째 예에는 충분한 (5,1) 및 18,14)의 10 진수 값이 있습니다.
    이는 결과 스케일과 정밀도가 잘리지 않음을 의미합니다 (블로우 참조)

첫 번째 및 세 번째 사례에 대한 추가 정보 ..

부서의 결과 규모는 max(6, s1 + p2 + 1)다음과 같습니다.

  • 첫 번째 예, 이것은 38 정밀도로 적하 (77) (참조 :도 6의 최소 마찬가지로 피사체를 강제된다 이것을 )
  • 세 번째 예는 24이므로 정밀도를 조정할 필요가 없습니다.

몇 가지 옵션이 있습니다

  • 클라이언트 코드에서 계산 (예 : .net)
  • CLR 함수를 사용하여 .net 계산 수행
  • 정확성의 상실로 살다
  • float를 사용하고 15 개의 유효 숫자로 최상으로 산다

마지막으로, /programming/423925/t-sql-decimal-division-accuracy/424052#424052에서 이것을 참조 하십시오


1

이것이 도움이되는지 확실하지는 않지만 내 임시 테이블 열이 10 진수로 설정되어 삽입에서 temp_table로 convert (decimal (15,2), 0.65)를 전달하고있었습니다. 이것은 자동 반올림이었습니다. 전달 된 것과 일치하도록 열 유형을 decimal (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

도움이 되었기를 바랍니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.