Menu

SQLite 숫자 함수: ROUND, ABS, CEIL, FLOOR 완벽 정리

SQLite에서 산술 연산하는 법 — ROUND, ABS, CEIL, FLOOR, MOD, POWER, SQRT, RANDOM과 한 번쯤은 꼭 당하는 정수 나눗셈 함정까지.

이 페이지에는 실행 가능한 에디터가 있습니다 — 편집하고 실행하면 결과를 바로 볼 수 있습니다.

SQLite에 생각보다 많은 수학 함수가 있다고?

SQLite는 미니멀한 DB로 유명하지만, 의외로 숫자 함수만큼은 꽤 풍부하게 갖추고 있습니다. 반올림부터 절댓값, 올림과 내림, 거듭제곱, 제곱근, 로그, 삼각함수, 난수까지 거의 다 있죠. 대부분의 sqlite 수학 함수는 3.35 버전(2021년)에서 추가되었기 때문에, 요즘 쓰는 환경 — Python에 내장된 것, Node, 또는 공식 CLI 등 — 이라면 별도 설정 없이 바로 사용할 수 있습니다.

본격적으로 들어가기 전에, 먼저 맛보기 예제부터 살펴볼게요:

함수 여섯 개, 결과 한 줄. 이번 페이지의 나머지 부분에서는 각 함수군이 어떤 용도로 쓰이는지, 그리고 알아두면 좋은 함정들을 하나씩 짚어보겠습니다.

ROUND: 가장 자주 쓰게 될 sqlite 반올림 함수

ROUND(value, digits)는 지정한 sqlite 소수점 자리수만큼 반올림해 줍니다. 두 번째 인자는 선택값이라 생략하면 정수 단위로 반올림되지만, 반환 타입은 여전히 부동소수점입니다:

몇 가지 짚고 넘어갈 점이 있습니다.

  • ROUND(3.14159)3이 아니라 3.0을 반환합니다. 정수가 필요하다면 CAST(ROUND(x) AS INTEGER)를 쓰거나, 단순히 버림이 목적이라면 CAST(x AS INTEGER)를 사용하세요.
  • SQLite는 "0에서 멀어지는 방향으로 반올림(round half away from zero)" 방식을 씁니다. 즉 2.53, -2.5-3이 됩니다. 일부 DB는 은행원 반올림(짝수로 반올림)을 쓰지만, SQLite는 그렇지 않습니다.
  • digits 인자에는 음수도 넣을 수 있습니다. 예를 들어 ROUND(1234.5, -2)는 100 단위로 반올림해서 1200을 돌려줍니다.

실무에서 가장 자주 쓰는 형태는 단연 금액 표시용 ROUND(price, 2)입니다.

ROUND와 CAST는 다릅니다

반올림하려는 의도로 CAST(x AS INTEGER)를 쓰다가 낭패를 보는 경우가 흔합니다.

CAST은 0 방향으로 잘라냅니다. 그냥 소수 부분을 버려버리는 거죠. 반면 ROUND는 가장 가까운 정수로 반올림합니다. 2.9 같은 값에서는 두 결과가 1만큼 차이 나게 됩니다. 원하는 동작이 무엇인지에 따라 골라 쓰면 됩니다.

ABS, SIGN — 숫자의 부호 다루기

ABS(x)는 절댓값을 돌려주고, SIGN(x)는 숫자의 부호에 따라 -1, 0, 1 중 하나를 반환합니다:

ABS는 그야말로 일꾼 같은 함수예요. "두 값이 얼마나 떨어져 있나?" 같은 질의에 딱입니다. SIGN은 자주 쓰이진 않지만, 별도의 CASE 문 없이도 행을 방향(입금 vs 출금, 이익 vs 손실)별로 분류할 때 요긴하죠.

CEIL, FLOOR, TRUNC 함수

이 세 함수는 가장 가까운 정수로 반올림하는 게 아니라, 정수 형태의 값을 얻어낼 때 씁니다. CEIL은 항상 위로 올림, FLOOR는 항상 아래로 내림, TRUNC는 항상 0 방향으로 잘라냅니다:

음수 케이스를 조심하세요. FLOOR(-2.9)-3(0에서 더 멀어짐)이지만, TRUNC(-2.9)-2(0 쪽으로 가까워짐)입니다. 음수를 다룰 때 FLOORTRUNC는 서로 다른 결과를 내기 때문에, 둘 중 잘못된 걸 고르면 전형적인 off-by-one 버그로 이어집니다.

CEILINGCEIL의 별칭입니다. 읽기 편한 쪽을 골라 쓰면 됩니다.

진짜 함정은 SQLite의 정수 나눗셈

이건 함수가 아니라 / 연산자 얘기지만, 어떤 수학 함수보다도 입문자들이 가장 많이 걸려 넘어지는 부분입니다:

양쪽 피연산자가 모두 정수면 SQLite는 정수 나눗셈을 수행하고 소수점 이하를 잘라냅니다. 한쪽이라도 REAL이 되는 순간 전체 식이 실수형으로 평가됩니다. 해결법은 간단해요. 적어도 한쪽 피연산자를 실수로 만들면 됩니다. 2 대신 2.0이라고 쓰거나, 명시적으로 캐스팅하면 됩니다.

이 함정은 컬럼을 참조할 때 특히 자주 발생합니다. total_cents / 100은 정수를 반환하지만, total_cents / 100.0이라고 쓰면 우리가 원했던 달러 단위 금액이 제대로 나옵니다.

MOD 함수와 % 연산자

MOD(x, y)x / y의 나머지를 돌려줍니다. % 연산자도 똑같은 동작을 합니다:

MOD(17, 5)17 % 5는 둘 다 2를 반환합니다. 그런데 SQLite에서 0으로 나눈 나머지는 에러를 내지 않고 NULL을 반환합니다. 대부분의 언어와 다른 부분이라 좀 의외인데, 이게 신경 쓰인다면 미리 나누는 값을 확인하거나 CASE WHEN y = 0 THEN ... END으로 감싸 두는 게 좋습니다.

함수 형태와 연산자 형태는 서로 바꿔 써도 됩니다. 보통은 짧다는 이유로 %를 더 많이 쓰죠.

POWER, SQRT, EXP, LOG

거듭제곱과 제곱근을 다룰 때 쓰는 함수들입니다:

사람들이 자주 헷갈리는 포인트 몇 가지를 짚고 갑니다:

  • POWPOWER의 별칭입니다.
  • SQLite의 LOG(x)상용로그(밑이 10) 입니다. LN(x)가 자연로그고요. 인자를 두 개 넘긴 LOG(b, x)는 밑이 b인 로그입니다. (다른 많은 언어에서는 log가 자연로그인데, SQL 쪽은 관례가 다르니 주의하세요.)
  • 음수에 SQRT를 적용하면 에러가 아니라 NULL이 반환됩니다.
  • POWER(0, 0)은 관례에 따라 1을 돌려줍니다.

복리 계산, 데시벨 정규화, 거리 계산처럼 기하급수적이거나 지수적인 수학이 들어가는 곳이라면 어디든 요긴하게 쓰입니다.

RANDOM과 RANDOMBLOB

RANDOM()은 부호 있는 64비트 정수 범위 전체에서 임의의 값을 반환합니다:

특정 범위의 숫자를 얻으려면 RANDOM()이 부호 있는 값을 반환하므로 ABS로 감싼 뒤 % 연산자를 사용하면 됩니다. 0과 1 사이의 실수를 얻고 싶다면 64비트 정수의 최댓값으로 나누면 됩니다. SQLite에는 0~1 사이 값을 돌려주는 내장 RAND() 함수가 없기 때문에 직접 만들어 써야 합니다.

RANDOMBLOB(n)n 바이트 분량의 임의 데이터를 반환하며, 세션 토큰이나 테스트용 더미 데이터를 만들 때 유용합니다. 출력 가능한 문자열로 바꾸려면 HEX()와 함께 사용하세요:

호출할 때마다 매번 새로운 값이 나옵니다. RANDOM()이 같은 행 안에서 두 번 같은 숫자를 돌려줄 거라고 기대하면 안 돼요. 한 표현식 안에서도 호출 하나하나가 서로 독립적으로 동작합니다.

한꺼번에 적용해 보기

상품 테이블을 예로 들어 거리를 계산하고 가격을 반올림하는 간단한 실전 예제를 살펴보겠습니다.

price_cents / 100.0에서 핵심은 바로 .0입니다. 이게 붙어야 나눗셈이 실수 연산으로 바뀌고, 그 결과를 ROUND로 소수점 둘째 자리까지 다듬을 수 있죠. 만약 .0을 빼면 1299 / 10012.99가 아니라 12가 됩니다 — sqlite 정수 나눗셈이 그렇게 동작하니까요.

다음 주제: 날짜와 시간

sqlite 숫자 함수로 수학 계산은 충분히 처리할 수 있습니다. 이제 날짜와 시간 차례인데, 이쪽은 별도의 도구가 필요합니다. SQLite는 날짜와 시간을 TEXT, REAL, INTEGER 중 하나로 저장하고, 이를 파싱하고 포맷팅하고 연산할 수 있는 작지만 강력한 함수들을 제공합니다. 다음 장에서 이 부분을 자세히 다뤄 보겠습니다.

자주 묻는 질문

SQLite에서 소수점 둘째 자리까지 반올림하려면?

ROUND(value, 2)를 쓰면 됩니다. 두 번째 인자가 남길 소수 자릿수예요. 예를 들어 ROUND(3.14159, 2)3.14를 반환합니다. 인자를 하나만 넘기면 — ROUND(x) — 가장 가까운 정수로 반올림하지만 반환 타입은 여전히 실수(float)라 헷갈릴 수 있으니 주의하세요.

SQLite에 CEIL이나 FLOOR도 있나요?

네, 있습니다. SQLite 3.35 (2021년)부터 수학 함수가 기본 내장됐어요. CEIL(x), FLOOR(x), SQRT(x), POWER(x, y), LOG(x), EXP(x) 등을 그대로 쓸 수 있습니다. 그 이전 버전에서는 math 확장을 따로 로드해야 하지만, 요즘 배포되는 환경(Python, Node, 브라우저 내장 등)은 거의 다 활성화된 상태로 들어옵니다.

왜 SQLite에서 5 / 2가 2.5가 아니라 2가 나오죠?

양쪽이 모두 정수라서 그렇습니다. 정수끼리 나누면 SQLite는 정수 나눗셈을 수행하고 소수점 이하를 버려버려요. 2.5를 얻으려면 한쪽을 실수로 만들어 주면 됩니다. 5 / 2.0이나 CAST(5 AS REAL) / 2처럼요. 이건 숫자 함수의 문제가 아니라 / 연산자가 정수 인자를 만났을 때의 동작 방식입니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기