본문 바로가기

전체보기/Database

[MSSQL] DECIMAL 사칙연산 파헤치기

이번 글에서는 DECIMAL 타입에서

사칙연산이 동작하는 방식에 대해서 정리해보겠습니다.

DECIMAL

연산에 대한 설명에 앞서서

간단하게 DECIMAL이라는 타입에 대해 알아보겠습니다.

 

DECIMAL은 Precision과 Scale로 정의되어 있습니다.

 

Precision은 전체 자릿수,

Scale은 .(점) 오른쪽에 오는, 소수 자릿수를 의미합니다.

 

SELECT CAST(1.0005 as DECIMAL(4, 3))

 

위 예시에서는 그림과 같이 

precision과 scale을 표시할 수 있고

scale의 범위를 넘은 소수점의 값(5)은 반올림 하여 

위 query의 결과는 1.001이 됩니다.

(정수가 자릿수를 초과할 경우에는 overflow error가 발생합니다.)

 

Calculation

그럼 DECIMAL 사칙연산은 무엇이 특별할까요?

먼저 간단한 query를 살펴보겠습니다.

 

DECLARE @foo DECIMAL(18, 4) = 3, @bar DECIMAL(18, 4) = 1;
SELECT @foo / @bar;

 

위 query 결과의 Precision과 Scale은 어떻게 될까요?

많은 분들이 각각 18, 4를 생각하시겠지만

생각 외로 정답은 38, 20입니다.

 

이러한 결과가 나오게 된 이유는

DECIMAL 계산이 아래 규칙을 따르기 때문입니다.

 

 

이 외에도 precision, scale에 따라 추가적으로 고려해야할

내용들이 있지만 개인적으로 수식과 규칙을 외우는 것이

중요하다고는 생각하지 않기 때문에

이 글에서는 따로 설명하지 않도록 하겠습니다.

궁금하신 분들은 링크를 참고해 주세요.

 

중요한 것은 연산과정에서 precision과 scale이 달라질 수도 있다는 점,

그리고 이로 인해 query의 결과가 달라질 수도 있다는 것

인식하는 것이라고 생각합니다.

 

Example

위 연산 과정이 어떤 영향을 미칠 수 있는지

간단한 예시를 보겠습니다.

 

DECLARE @foo decimal(18,4) = 1, @bar decimal(18,4) = 3;
DECLARE @result decimal(18, 4) = @foo / @bar;
SELECT @result * @bar as Result;

DECLARE @foo2 decimal(18,4) = 1, @bar2 decimal(18,4) = 3;
SELECT ( @foo2 / @bar2 ) * @bar2 as Result;

 

얼핏보면 두 query는 차이가 없어보이지만

결과는 다르게 나옵니다.

 

정답을 보기 전에 고민해보시면 왜 다른 결과가 나오게 되는지

고민해보시면 좋을 것 같습니다.

 

.

.

.

.

.

.

 

위, 아래 query의 결과는 각각

0.99990000(precision: 37, scale: 8)

1.000000(precision: 38, scale: 6)

입니다.

 

 

그럼 여기까지 DECIMAL의 사칙연산에 대해

간단하게 정리해봤습니다.

 

틀린 부분이나 궁금한 점이 있으면

댓글 부탁드리겠습니다.

Reference

docs.microsoft.com/en-us/sql/t-sql/data-types/precision-scale-and-length-transact-sql?redirectedfrom=MSDN&view=sql-server-ver15

 

 

반응형