postgresql trunc 함수를 알아봅시다.

코딩/Sql 2023. 6. 27. 23:58

 postgresql에서 trunc 함수는 무엇일까요? 0 이상의 double형에서는 소수점을 버리기 위해, 미만인 경우 올림 처리를 하기 위해 쓰게 됩니다. 수학적으로 즉 0 이상에서는 floor와, 미만에서는 ceil과 동일하다고 할 수 있어요.


 trunc(-1.23, 1)을 보겠습니다. 소수점 1째 자리까지 나타냅니다. trunc한 결과를요. -1.23은 0보다는 작으므로 ceil을 하게 됩니다. -1.3은 -1.23보다는 작고, -1.2는 -1.23보다는 크거나 같습니다. 따라서, -1.2가 출력됩니다.

 

 실행 결과는 위와 같습니다. trunc의 2번째 인자에 아무것도 주지 않으면 0보다 크거나 같은 경우 floor를, 작은 경우 ceiling을 하게 되는데요. 아래 예제를 보겠습니다.

 

 select trunc(1.2)를 보겠습니다. floor를 하니까 1.2보다 작거나 같은 정수 중 제일 큰 것을 찾아야 합니다. 1인가요?

 

 따라서 1이 출력됩니다.

 


 저는 이 함수를 random과 많이 쓰는 편입니다. 아래 예제를 보겠습니다.

 

 이 예제는 generate_series를 이용해서, trunc(random() * 11)을 한 결과를 10만개를 뽑은 결과를 가지고 min값과 max값을 집계해 버립니다. 결과를 보겠습니다.

 

 0과 10이 나오네요. 만약에 0보다 크고 10보다 작은 수를 랜덤하게 n회 뽑는 것은 generate_series와 random, trunc를 이용해서 가능하다는 이야기입니다. 한 가지 조심해야 할 점은 trunc의 경우 double precision이 들어가게 되면, 결과값으로 double precision이 나온다는 점입니다.

 

 

 pg_typeof 함수로 trunc(random()*10)의 type이 어떤 것인지 출력해 보겠습니다.

 

 

 double precision이 뜨네요. 따라서, 정수로 처리해야 한다면 뒤에 ::integer를 붙여서, 형을 변환해야 할 필요가 있습니다. 여기서 한 가지 질문. 그냥 random() * 10의 결과에 ::integer를 붙여도 되지 않나요? 이런 것을 검증하기 가장 쉬운 방법은 극단적인 케이스를 넣어보는 것입니다. 10.5와 같은 경계값을 넣어봅시다.

 

 

 select 10.5::integer, trunc(10.5)::integer 이 두 값을 비교해 보겠습니다.

 

그랬더니 전자는 11이, 후자는 double precision 10이 나왔습니다. 고로 0보다 크거나 같은 경우, 정수값만 취하고 싶다. 그러면, trunc, floor 등을 이용해서 선처리를 해야 합니다. 그 이후에 정수형으로 바꿔야 한다. 그러면 ::integer나 ::bigint 등으로 형 변환 시켜버리면 됩니다.