LISTAGG
LISTAGG (목록 결합)
입력 값을 구분자(delimiter) 문자열로 구분하여 연결(concatenate)한 값을 반환해요.
본문
구문 (Syntax)
집계 함수(Aggregate function):
LISTAGG( [ DISTINCT ] <expr1> [, <delimiter> ] )
[ WITHIN GROUP ( <orderby_clause> ) ]
창 함수(Window function):
LISTAGG( [ DISTINCT ] <expr1> [, <delimiter> ] )
[ WITHIN GROUP ( <orderby_clause> ) ]
OVER ( [ PARTITION BY <expr2> ] )
필수 인자 (Required arguments)
expr1
목록에 넣을 값을 결정하는 표현식(일반적으로 열 이름)이에요. 표현식은 문자열 또는 문자열로 캐스팅할 수 있는 데이터 타입으로 평가되어야 해요.
OVER()
OVER 절은 함수를 창 함수로 사용할 때 필요해요. 자세한 내용은 Window function syntax and usage를 참고하세요.
선택 인자 (Optional arguments)
DISTINCT
목록에서 중복 값을 제거해요.
delimiter
문자열 또는 문자열로 평가되는 표현식이에요. 일반적으로 이 값은 단일 문자 문자열이에요. 아래 예시처럼 문자열은 작은따옴표로 감싸야 해요. 구분자를 지정하지 않으면 빈 문자열이 구분자로 사용돼요. 구분자는 상수(constant)여야 해요.
WITHIN GROUP orderby_clause
목록의 각 그룹에 대해 값의 순서를 결정하는 하나 이상의 표현식(일반적으로 열 이름)이에요. WITHIN GROUP (ORDER BY) 구문은 SELECT 문의 ORDER BY 절과 같은 파라미터를 지원해요.
PARTITION BY expr2
함수를 적용하기 전에 입력 행을 그룹화하는 파티션을 정의하는 표현식(일반적으로 열 이름)을 지정하는 창 함수 하위 절이에요. 자세한 내용은 Window function syntax and usage를 참고하세요.
반환 값 (Returns)
구분자로 구분된 모든 비-NULL 입력 값을 포함하는 문자열을 반환해요.
이 함수는 목록이나 배열을 반환하지 않아요. 모든 비-NULL 입력 값이 포함된 단일 문자열을 반환해요.
사용 참고 사항 (Usage notes)
WITHIN GROUP (ORDER BY)를 지정하지 않으면 각 목록 내 요소의 순서는 예측할 수 없어요. (WITHIN GROUP 절 밖의 ORDER BY 절은 목록 요소의 순서가 아니라 출력 행의 순서에 적용돼요.)
WITHIN GROUP (ORDER BY)의 표현식에 숫자를 지정하면 이 숫자는 SELECT 목록에서 열의 서수 위치가 아니라 숫자 상수로 구문 분석돼요. 따라서 WITHIN GROUP (ORDER BY) 표현식으로 숫자를 지정하지 마세요.
DISTINCT와 WITHIN GROUP을 모두 지정하면 둘 다 같은 열을 가리켜야 해요. 예:
SELECT LISTAGG(DISTINCT O_ORDERKEY) WITHIN GROUP (ORDER BY O_ORDERKEY) ...;
DISTINCT와 WITHIN GROUP에 서로 다른 열을 지정하면 오류가 발생해요:
SELECT LISTAGG(DISTINCT O_ORDERKEY) WITHIN GROUP (ORDER BY O_ORDERSTATUS) ...;
-- SQL compilation error: [ORDERS.O_ORDERSTATUS] is not a valid order by expression
DISTINCT와 WITHIN GROUP에 같은 열을 지정하거나 DISTINCT를 생략해야 해요.
NULL 또는 빈 입력 값에 대해: 입력이 비어 있으면 빈 문자열을 반환해요. 모든 입력 표현식이 NULL로 평가되면 출력은 빈 문자열이에요. 일부 입력 표현식만 NULL로 평가되면 출력에는 모든 비-NULL 값이 포함되고 NULL 값은 제외돼요.
이 함수를 창 함수로 호출하면 다음을 지원하지 않아요: OVER 절 내의 ORDER BY 절, 명시적 창 프레임(window frames).
데이터 정렬(Collation) 세부 사항
결과의 collation은 입력의 collation과 같아요.
ORDER BY 하위 절이 collation이 있는 표현식을 지정하면 목록 내 요소는 collation에 따라 정렬돼요.
구분자는 collation 사양을 사용할 수 없어요.
ORDER BY 안에 collation을 지정해도 결과의 collation에는 영향을 주지 않아요. 예를 들어 아래 명령문에는 LISTAGG용과 쿼리 결과용 두 개의 ORDER BY 절이 있어요. 첫 번째 절 안에 collation을 지정해도 두 번째 절에는 영향을 주지 않아요. 두 ORDER BY 절 모두에서 출력을 정렬해야 한다면 두 절 모두에 collation을 명시적으로 지정해야 해요.
SELECT LISTAGG(x, ',') WITHIN GROUP (ORDER BY last_name COLLATE 'es') FROM table1 ORDER BY last_name;
예시 (Examples)
이 예시들은 LISTAGG 함수를 사용해요.
LISTAGG 함수로 쿼리 결과의 값 연결
다음 예시들은 orders 데이터에 대한 쿼리 결과의 값을 연결하기 위해 LISTAGG 함수를 사용해요.
참고: 이 예시들은 TPC-H 샘플 데이터를 쿼리해요. 쿼리를 실행하기 전에 다음 SQL 문을 실행하세요:
USE SCHEMA snowflake_sample_data.tpch_sf1;
이 예시는 o_totalprice가 520000보다 큰 주문의 고유한 o_orderkey 값을 나열하고 구분자로 빈 문자열을 사용해요:
SELECT LISTAGG(DISTINCT o_orderkey, ' ')
FROM orders
WHERE o_totalprice > 520000;
+-------------------------------------------------+
| LISTAGG(DISTINCT O_ORDERKEY, ' ') |
|-------------------------------------------------|
| 2232932 1750466 3043270 4576548 4722021 3586919 |
+-------------------------------------------------+
이 예시는 o_totalprice가 520000보다 큰 주문의 고유한 o_orderstatus 값을 나열하고 구분자로 세로 막대(|)를 사용해요:
SELECT LISTAGG(DISTINCT o_orderstatus, '|')
FROM orders
WHERE o_totalprice > 520000;
+--------------------------------------+
| LISTAGG(DISTINCT O_ORDERSTATUS, '|') |
|--------------------------------------|
| O|F |
+--------------------------------------+
이 예시는 o_totalprice가 520000보다 크고 o_orderstatus로 그룹화된 각 주문의 o_orderstatus와 o_clerk 값을 나열해요. 이 쿼리는 구분자로 쉼표를 사용해요:
SELECT o_orderstatus,
LISTAGG(o_clerk, ', ')
WITHIN GROUP (ORDER BY o_totalprice DESC)
FROM orders
WHERE o_totalprice > 520000
GROUP BY o_orderstatus;
+---------------+---------------------------------------------------+
| O_ORDERSTATUS | LISTAGG(O_CLERK, ', ') |
| | WITHIN GROUP (ORDER BY O_TOTALPRICE DESC) |
|---------------+---------------------------------------------------|
| O | Clerk#000000699, Clerk#000000336, Clerk#000000245 |
| F | Clerk#000000040, Clerk#000000230, Clerk#000000924 |
+---------------+---------------------------------------------------+
LISTAGG 함수와 함께 collation 사용
다음 예시들은 LISTAGG 함수와 collation을 보여줘요. 예시들은 다음 데이터를 사용해요:
CREATE OR REPLACE TABLE collation_demo (
spanish_phrase VARCHAR COLLATE 'es');
INSERT INTO collation_demo (spanish_phrase) VALUES
('piña colada'),
('Pinatubo (Mount)'),
('pint'),
('Pinta');
collation 사양이 다르면 출력 순서가 다르다는 점을 주목하세요. 이 쿼리는 es collation 사양을 사용해요:
SELECT LISTAGG(spanish_phrase, '|')
WITHIN GROUP (ORDER BY COLLATE(spanish_phrase, 'es')) AS es_collation
FROM collation_demo;
+-----------------------------------------+
| ES_COLLATION |
|-----------------------------------------|
| Pinatubo (Mount)|pint%Pinta%piña colada |
+-----------------------------------------+
이 쿼리는 utf8 collation 사양을 사용해요:
SELECT LISTAGG(spanish_phrase, '|')
WITHIN GROUP (ORDER BY COLLATE(spanish_phrase, 'utf8')) AS utf8_collation
FROM collation_demo;
+-----------------------------------------+
| UTF8_COLLATION |
|-----------------------------------------|
| Pinatubo (Mount)|Pinta%pint%piña colada |
+-----------------------------------------+
더 알아보기 (Learn more)
- Aggregate functions — 집계 함수 모음
- Window function syntax and usage — 창 함수 구문
- ARRAY_AGG — 배열로 결합