{#unwind-unwind}
# UNWIND
리스트를 행으로 바꿉니다. 요소 하나마다 작업 행 하나입니다.
{#unwind-synopsis}
## 개요
UNWINDlist_expressionASvariable
굵게 키워드 · 기울임 직접 채우는 자리 · [ ] 생략 가능 · ... 반복 가능. 구문 표기 규약을 참고하십시오.
{#unwind-description}
## 설명
`UNWIND`는 리스트를 파이프라인으로 펼칩니다. 요소마다 행 하나를 내놓고 *variable*을 그 요소에
바인딩하며, 이미 유효 범위에 있던 나머지는 그대로 함께 이어집니다. `collect()`의 역이고, 리스트를
담은 한 행에서 그 조각들을 담은 여러 행으로 가는 방법입니다.
- `AS variable`은 **필수**입니다. 이름 없는 형태는 없습니다.
- 리스트는 **리터럴**, **리스트 값을 가진 속성**, `collect()`가 만든 변수, 또는 jsonb 배열이나
PostgreSQL 배열을 내놓는 표현식이면 됩니다. 스칼라는 거부됩니다.
- **빈 리스트**는 행을 내놓지 않으므로, 입력 행 전체가 사라집니다.
- 리스트 **안의 null**도 다른 요소와 같은 요소이고 행을 만듭니다.
- `UNWIND`는 들어오는 행마다 한 번 실행되고, 내놓는 행은 곱해집니다. 입력 행 셋에 요소 둘인 리스트면
여섯 행입니다.
- `UNWIND`는 쿼리를 시작하거나 다른 절 뒤에 올 수 있습니다. 쿼리를 끝낼 수는 없습니다.
- 리스트의 리스트를 펼치려면 `UNWIND` 절 두 개를 겹쳐 쓰십시오.
[`FOR`](for.md)가 GQL의 대응 절이고 같은 일을 하며, 순번을 선택적으로 함께 줍니다.
{#unwind-parameters}
## 매개변수
list_expression
: jsonb 배열이나 PostgreSQL 배열을 내놓는 표현식입니다.
variable
: 각 요소에 바인딩되는 이름입니다. 이 절 뒤의 모든 절에서 보입니다.
{#unwind-examples}
## 예제
모든 예제는 [예제 데이터셋](../../get_started/example-dataset.md)에서 실행됩니다.
{#unwind-expand-a-list-literal}
### 리스트 리터럴 펼치기
```cypher
UNWIND [1, 91, 203, 1, 7, 91] AS n
RETURN n;
```
```
n
-----
1
91
203
1
7
91
(6 rows)
```
리스트 순서대로 여섯 행이며, 중복도 포함됩니다.
{#unwind-deduplicate-and-sort-a-list}
### 리스트를 중복 제거하고 정렬하기
리스트를 제자리에서 `DISTINCT` 처리하는 방법은 없습니다. 그것을 펼치고, 행의 중복을 없애고, 다시
모으십시오:
```cypher
UNWIND [1, 91, 203, 1, 7, 91] AS n
WITH DISTINCT n
ORDER BY n
RETURN collect(n) AS uniq;
```
```
uniq
-----------------
[1, 7, 91, 203]
(1 row)
```
{#unwind-drive-a-match-from-a-list}
### 리스트로 MATCH를 돌리기
요소마다 행 하나이고, 각각 차례로 일치됩니다:
```cypher
UNWIND ['The Matrix', 'Inception'] AS t
MATCH (m:movie {title: t})
RETURN m.title AS film, m.year AS year;
```
```
film | year
--------------+------
"The Matrix" | 1999
"Inception" | 2010
(2 rows)
```
클라이언트가 준 키 목록에 대해 쿼리를 실행하는 흔한 방법이 이것이며, 그 목록은 매개변수 하나로
넘깁니다.
{#unwind-expand-a-list-valued-property}
### 리스트 값을 가진 속성 펼치기
속성이 리스트를 담을 수 있고, `UNWIND`가 그것을 엽니다:
```cypher
MATCH (m:movie {title: 'The Matrix'})
UNWIND m.embedding AS component
RETURN component;
```
```
component
-------------
-0.07594558
0.04081754
0.29592122
-0.11921061
(4 rows)
```
{#unwind-undo-a-collect}
### collect 되돌리기
`collect()`는 행을 리스트로 접고, `UNWIND`는 그것을 다시 펼칩니다. 집계한 다음 행으로 돌아가는
방법이 이 짝입니다:
```cypher
MATCH (p:person)-[:acted_in]->(m:movie)
WITH collect(DISTINCT m.genre) AS genres
UNWIND genres AS genre
RETURN genre
ORDER BY genre;
```
```
genre
-------------
"Action"
"Adventure"
"Sci-Fi"
(3 rows)
```
{#unwind-flatten-a-list-of-lists}
### 리스트의 리스트 펼치기
`UNWIND` 절 두 개이고, 두 번째는 첫 번째가 바인딩한 변수를 대상으로 합니다:
```cypher
UNWIND [[1, 2], [3]] AS pair
UNWIND pair AS x
RETURN pair, x;
```
```
pair | x
--------+---
[1, 2] | 1
[1, 2] | 2
[3] | 3
(3 rows)
```
{#unwind-expand-an-empty-list}
### 빈 리스트 펼치기
행이 하나도 나오지 않고, 입력 행도 함께 사라집니다:
```cypher
UNWIND [] AS x RETURN x;
```
```
x
---
(0 rows)
```
빈 리스트에서도 행이 살아남아야 한다면 [`OPTIONAL MATCH`](optional-match.md)나 `CASE` 보호 장치를
쓰십시오.
{#unwind-keep-the-nulls}
### null을 남기기
null인 요소도 요소입니다:
```cypher
UNWIND [1, NULL, 3] AS x RETURN x;
```
```
x
------
1
null
3
(3 rows)
```
값이 `null`로 출력되는 것은 출력 컬럼이 jsonb이고, jsonb의 null은 없는 것이 아니라 하나의 값이기
때문입니다.
{#unwind-notes}
## 참고
`UNWIND`에는 리스트가 필요합니다. 스칼라도, `NULL`만 쓴 것도 요소 하나짜리나 요소 없는 리스트로
취급되지 않습니다:
```cypher
UNWIND 3 AS x RETURN x;
```
```
ERROR: expression must be jsonb or array, but integer
LINE 1: UNWIND 3 AS x RETURN x;
^
```
```cypher
UNWIND NULL AS x RETURN x;
```
```
ERROR: expression must be jsonb or array, but unknown
LINE 1: UNWIND NULL AS x RETURN x;
^
```
속성이 반드시 있다고 보장되지 않는다면, `UNWIND coalesce(m.tags, []) AS tag`처럼 리스트가 아닐 수
있는 값을 감싸십시오.
{#unwind-compatibility}
## 호환성
{#unwind-unwind-is-not-a-gql-clause}
### UNWIND는 GQL 절이 아니다
ISO/IEC 39075에는 `UNWIND`가 없습니다. 리스트를 펼치는 표준의 문장은 ``(§14.8)이고,
AgensGraph는 그것도 [`FOR`](for.md)로 구현하고 있습니다. `FOR`에는 각 요소에 0부터 시작하는 위치를
주는 `WITH OFFSET` 절이 있는데, `UNWIND`는 그것을 할 수 없습니다.
{#unwind-see-also}
## 관련 항목
- [`FOR`](for.md) {bdg-primary-line}`GQL` — 순번이 있는 표준 절
- [`WITH`](with.md) — `collect()`가 놓이는 자리, 그리고 행의 중복을 없애는 방법
- [`MATCH`](match.md) — 펼친 행으로 일치를 돌리기
- [함수](../functions/index) — `collect()`와 그 밖의 리스트 함수들