내장 집계 함수
내장 집계 함수
이 페이지에서는 SQLite가 제공하는 내장 집계 함수들에 대해 설명해요. COUNT, SUM, AVG, MIN, MAX 등과 같은 함수들의 문법과 동작 방식을 확인할 수 있어요.
출처: 문서
본문
1. 구문
aggregate-function-invocation:
aggregate-func ( DISTINCT expr ) filter-clause , * ORDER BY ordering-term ,
expr:
literal-value bind-parameter schema-name . table-name . column-name unary-operator expr expr binary-operator expr function-name ( function-arguments ) filter-clause over-clause ( expr ) , CAST ( expr AS type-name ) expr COLLATE collation-name expr NOT LIKE GLOB REGEXP MATCH expr expr ESCAPE expr expr ISNULL NOTNULL NOT NULL expr IS NOT DISTINCT FROM expr expr NOT BETWEEN expr AND expr expr NOT IN ( select-stmt ) expr , schema-name . table-function ( expr ) table-name , NOT EXISTS ( select-stmt ) CASE expr WHEN expr THEN expr ELSE expr END raise-function
function-arguments:
DISTINCT expr , * ORDER BY ordering-term ,
literal-value:
CURRENT_TIMESTAMP numeric-literal string-literal blob-literal NULL TRUE FALSE CURRENT_TIME CURRENT_DATE
over-clause:
OVER window-name ( base-window-name PARTITION BY expr , ORDER BY ordering-term , frame-spec )
frame-spec:
GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING RANGE ROWS UNBOUNDED PRECEDING expr PRECEDING CURRENT ROW expr PRECEDING CURRENT ROW expr FOLLOWING expr PRECEDING CURRENT ROW expr FOLLOWING EXCLUDE CURRENT ROW EXCLUDE GROUP EXCLUDE TIES EXCLUDE NO OTHERS
raise-function:
RAISE ( ROLLBACK , expr ) IGNORE ABORT FAIL
select-stmt:
WITH RECURSIVE common-table-expression , SELECT DISTINCT result-column , ALL FROM table-or-subquery join-clause , WHERE expr GROUP BY expr HAVING expr , WINDOW window-name AS window-defn , VALUES ( expr ) , , compound-operator select-core ORDER BY LIMIT expr ordering-term , OFFSET expr , expr
common-table-expression:
table-name ( column-name ) AS NOT MATERIALIZED ( select-stmt ) ,
compound-operator:
UNION UNION INTERSECT EXCEPT ALL
join-clause:
table-or-subquery join-operator table-or-subquery join-constraint
join-constraint:
USING ( column-name ) , ON expr
join-operator:
NATURAL LEFT OUTER JOIN , RIGHT FULL INNER CROSS
result-column:
expr AS column-alias * table-name . *
table-or-subquery:
schema-name . table-name AS table-alias INDEXED BY index-name NOT INDEXED table-function-name ( expr ) , AS table-alias ( select-stmt ) ( table-or-subquery ) , join-clause
window-defn:
( base-window-name PARTITION BY expr , ORDER BY ordering-term , frame-spec )
frame-spec:
GROUPS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING RANGE ROWS UNBOUNDED PRECEDING expr PRECEDING CURRENT ROW expr PRECEDING CURRENT ROW expr FOLLOWING expr PRECEDING CURRENT ROW expr FOLLOWING EXCLUDE CURRENT ROW EXCLUDE GROUP EXCLUDE TIES EXCLUDE NO OTHERS
type-name:
name ( signed-number , signed-number ) ( signed-number )
signed-number:
+ numeric-literal -
filter-clause:
FILTER ( WHERE expr )
ordering-term:
expr COLLATE collation-name DESC ASC NULLS FIRST NULLS LAST
아래에 보이는 집계 함수들은 기본적으로 사용할 수 있어요. JSON SQL 함수와 함께 분류되는 집계 함수가 두 개 더 있어요. 애플리케이션은 sqlite3_create_function() 인터페이스를 사용하여 사용자 정의 집계 함수를 정의할 수 있어요.
단일 인자를 받는 집계 함수에서는 그 인자 앞에 DISTINCT 키워드를 붙일 수 있어요. 이 경우 중복 요소는 집계 함수로 전달되기 전에 걸러져요. 예를 들어 "count(distinct X)" 함수는 X 열의 NULL이 아닌 값의 총 개수 대신 X 열의 고유 값 개수를 반환해요.
FILTER 절을 지정하면 expr이 참인 행만 집계에 포함돼요.
ORDER BY 절을 지정하면 집계 입력이 처리되는 순서가 그 절에 의해 결정돼요. max()나 count() 같은 집계 함수에서는 입력 순서가 중요하지 않아요. 하지만 string_agg()나 json_group_object() 같은 경우에는 ORDER BY 절이 결과에 영향을 줄 수 있어요. ORDER BY 절을 지정하지 않으면 집계 입력은 호출할 때마다 달라질 수 있는 임의의 순서로 처리돼요.
참고: 스칼라 함수와 윈도우 함수.
2. 내장 집계 함수 목록
-
avg(X)
-
count(*)
-
count(X)
-
group_concat(X)
-
group_concat(X,Y)
-
max(X)
-
median(X)
-
min(X)
-
percentile(Y,P)
-
percentile_cont(Y,P)
-
percentile_disc(Y,P)
-
string_agg(X,Y)
-
sum(X)
-
total(X)
3. 내장 집계 함수 설명
** avg(X)
avg() 함수는 그룹 내 모든 NULL이 아닌 X의 평균값을 반환해요. 숫자처럼 보이지 않는 문자열과 BLOB 값은 0으로 해석돼요. 입력 중 NULL이 아닌 값이 하나라도 있으면, 모든 입력이 정수일 때에도 avg()의 결과는 항상 부동 소수점 값이에요. NULL이 아닌 입력이 없으면 avg()의 결과는 NULL이에요. avg()의 결과는 total()/count()로 계산되므로, total()에 적용되는 모든 제약 조건은 avg()에도 동일하게 적용돼요.
** count(X) count()*
count(X) 함수는 그룹에서 X가 NULL이 아닌 횟수를 반환해요. count(*) 함수(인자 없음)는 그룹의 전체 행 수를 반환해요.
** group_concat(X) group_concat(X,Y) string_agg(X,Y)**
group_concat() 함수는 X의 NULL이 아닌 모든 값을 연결한 문자열을 반환해요. Y 매개변수가 있으면 X 값 사이의 구분자로 사용돼요. Y가 생략되면 쉼표(",")가 구분자로 사용돼요.
string_agg(X,Y) 함수는 group_concat(X,Y)의 별칭이에요. String_agg()는 PostgreSQL 및 SQL-Server와 호환되고, group_concat()은 MySQL과 호환돼요.
연결된 요소의 순서는 마지막 매개변수 바로 뒤에 ORDER BY 인자를 포함하지 않는 한 임의예요.
** max(X)**
max() 집계 함수는 그룹의 모든 값 중 최댓값을 반환해요. 최댓값은 같은 열에 대해 ORDER BY를 수행했을 때 마지막으로 반환되는 값이에요. 집계 max()는 그룹에 NULL이 아닌 값이 없을 때만 NULL을 반환해요.
** median(X)**
median() 함수는 그룹 내 모든 NULL이 아닌 X의 중앙값(median)을 반환해요. median(X) 함수는 percentile_cont(X,0.5)와 동일해요. 자세한 내용은 percentile 확장에 대한 별도 문서를 참조하세요.
median() 함수는 amalgamation을 -DSQLITE_ENABLE_PERCENTILE로 컴파일한 경우 SQLite 3.51.0(2025-11-04)부터 사용할 수 있어요. 이전 버전의 SQLite에서는 로드 가능한 확장으로 사용할 수 있어요.
** min(X)**
min() 집계 함수는 그룹의 모든 값 중 NULL이 아닌 최솟값을 반환해요. 최솟값은 해당 열을 ORDER BY 했을 때 가장 먼저 나타나는 NULL이 아닌 값이에요. 집계 min()은 그룹에 NULL이 아닌 값이 없을 때만 NULL을 반환해요.
** percentile(Y,P)**
percentile(Y,P) 집계 함수는 NULL이 아닌 입력 중 P퍼센트가 X 이하가 되고, 입력 중 100-P퍼센트가 X 이상이 되는 값 X를 계산해요. 매개변수 P는 0.0과 100.0 사이의 숫자여야 해요. P 값은 집계의 모든 항에서 동일해야 하며 NULL이 될 수 없어요. Y 입력은 NULL이거나 숫자여야 해요. Y의 NULL 값은 무시돼요. NULL이 아닌 Y 입력 중 숫자가 아니면 오류가 발생해요.
percentile(Y,P) 함수는 percentile_cont(Y,p/100.0)와 동일해요. 자세한 내용은 percentile 확장에 대한 별도 문서를 참조하세요.
percentile() 함수는 amalgamation을 -DSQLITE_ENABLE_PERCENTILE로 컴파일한 경우 SQLite 3.51.0(2025-11-04)부터 사용할 수 있어요. 이전 버전의 SQLite에서는 로드 가능한 확장으로 사용할 수 있어요.
** percentile_cont(Y,P)**
percentile_cont(Y,P) 집계 함수는 NULL이 아닌 입력 중 비율 P가 X 이하가 되고, 입력 중 비율 1.0-P가 X 이상이 되는 값 X를 계산해요. 매개변수 P는 0.0과 1.0 사이의 숫자여야 해요. P 값은 집계의 모든 항에서 동일해야 하며 NULL이 될 수 없어요. Y 입력은 NULL이거나 숫자여야 해요. Y의 NULL 값은 무시돼요. NULL이 아닌 Y 입력 중 숫자가 아니면 오류가 발생해요.
percentile_cont(Y,P) 함수는 P 값의 범위가 0.0100.0 대신 0.01.0이라는 점을 제외하면 percentile(Y,P)와 동일하게 동작해요. 따라서 percentile_cont(Y,P)의 결과는 percentile(Y,P*100)과 같아요. 자세한 내용은 percentile 확장에 대한 별도 문서를 참조하세요.
percentile_cont() 함수는 amalgamation을 -DSQLITE_ENABLE_PERCENTILE로 컴파일한 경우 SQLite 3.51.0(2025-11-04)부터 사용할 수 있어요. 이전 버전의 SQLite에서는 로드 가능한 확장으로 사용할 수 있어요.
** percentile_disc(Y,P)**
percentile_disc(Y,P) 함수는 percentile_cont(Y,P)와 유사하지만, 가장 가까운 사용 가능한 입력들의 가중 평균을 구하는 대신 항상 입력 값 중 하나를 반환해요. 즉, 두 가능한 선택 중 더 작은 값을 반환해요. 자세한 내용은 percentile 확장에 대한 별도 문서를 참조하세요.
percentile_cont() 함수는 amalgamation을 -DSQLITE_ENABLE_PERCENTILE로 컴파일한 경우 SQLite 3.51.0(2025-11-04)부터 사용할 수 있어요. 이전 버전의 SQLite에서는 로드 가능한 확장으로 사용할 수 있어요.
** sum(X) total(X)**
sum()과 total() 집계 함수는 그룹의 모든 NULL이 아닌 값의 합을 반환해요. NULL이 아닌 입력 행이 없으면 sum()은 NULL을 반환하지만 total()은 0.0을 반환해요. 행이 없을 때 sum()의 결과로 NULL을 반환하는 것은 일반적으로 유용하지 않지만, SQL 표준에서 요구하고 대부분의 다른 SQL 데이터베이스 엔진도 sum()을 그렇게 구현하고 있어요. SQLite도 호환성을 위해 동일하게 동작해요. 비표준 함수인 total()은 SQL 언어의 이런 설계 문제를 우회하기 위한 편리한 방법으로 제공돼요.
total()의 결과는 항상 부동 소수점 값이에요. sum()의 결과는 모든 NULL이 아닌 입력이 정수일 때 정수 값이에요. sum()에 대한 입력 중 정수도 NULL도 아닌 값이 하나라도 있으면 sum()은 수학적 합의 근삿값인 부동 소수점 값을 반환해요.
sum()은 모든 입력이 정수이거나 NULL이고 계산 중 어느 시점에서 정수 오버플로가 발생하면 "integer overflow" 예외를 발생시켜요. 이전 입력 중 부동 소수점 값이 하나라도 있으면 오버플로 오류가 발생하지 않아요. total()은 절대 정수 오버플로를 발생시키지 않아요.
부동 소수점 값을 합산할 때 값의 크기가 크게 다르면 IEEE 754 부동 소수점 값이 근사값이기 때문에 결과가 부정확할 수 있어요. 부동 소수점 숫자의 정확한 합산을 얻으려면 decimal 확장의 decimal_sum(X) 집계를 사용하세요. 다음 테스트 사례를 살펴볼게요.
**
CREATE TABLE t1(x REAL);
INSERT INTO t1 VALUES(1.55e+308),(1.23),(3.2e-16),(-1.23),(-1.55e308);
SELECT sum(x), decimal_sum(x) FROM t1;
큰 값 ±1.55e+308은 서로 상쇄되지만, 그 상쇄는 합산이 끝날 때까지 발생하지 않아요. 그 사이에 큰 값 +1.55e+308이 아주 작은 값 3.2e-16을 삼켜 버려요. 그 결과 sum()은 부정확한 결과를 내요. decimal_sum() 집계는 추가 CPU와 메모리 사용을 대가로 정확한 답을 생성해요. 또한 decimal_sum()은 SQLite 코어에 내장되어 있지 않고 로드 가능한 확장이라는 점도 참고하세요.
입력의 합이 IEEE 754 부동 소수점 값으로 표현하기에 너무 크면 +Infinity 또는 -Infinity 결과가 반환될 수 있어요. 부호가 다른 매우 큰 값들이 사용되어 SUM() 또는 TOTAL() 함수가 올바른 결과가 +Infinity인지 -Infinity인지 또는 그 사이의 다른 값인지 결정할 수 없으면 결과는 NULL이 돼요. 예를 들어 다음 쿼리는 NULL을 반환해요.
**
WITH t1(x) AS (VALUES(1.0),(-9e+999),(2.0),(+9e+999),(3.0))
SELECT sum(x) FROM t1;
이 페이지는 2025-11-13 07:12:58Z에 마지막으로 업데이트되었습니다.