{#aggregate-aggregate-functions} # 집계 함수 행의 묶음을 하나의 값으로 줄이는 함수들입니다. Cypher는 SQL과 같은 방식으로 그룹을 만듭니다. `RETURN`이나 `WITH` 목록에서 집계되지 않은 모든 표현식이 그룹화 키입니다. 키가 아예 없으면 결과 전체가 하나의 그룹입니다. 예제는 [예제 데이터셋](../../get_started/example-dataset.md)에서 실행됩니다. {#aggregate-avg} ## avg ``` avg ( expression numeric ) -> numeric ``` 그룹에서 null이 아닌 값들의 산술 평균을 반환합니다. **고려할 점** - 속성은 `jsonb`로 들어와 `numeric`으로 변환되므로, 결과는 `numeric`이고 `double precision`으로 둥글려지지 않고 정밀도를 온전히 유지합니다. - 값이 null인 행은 건너뜁니다. null이 아닌 값이 하나도 없는 그룹은 null을 반환합니다. ```cypher MATCH (m:movie) RETURN avg(m.year) AS mean_year; ``` ``` mean_year ----------------------- 2002.0555555555555556 ``` {#aggregate-collect} ## collect ``` collect ( expression anyelement ) -> jsonb collect ( v vertex ) -> vertex[] collect ( e edge ) -> edge[] collect ( p graphpath ) -> graphpath[] ``` 그룹의 값들을 그 그룹의 행 순서대로 리스트에 모읍니다. **고려할 점** - `vertex`·`edge`·`graphpath` 인자는 `jsonb` 배열이 아니라 그 타입 그대로의 배열을 만듭니다. 각각 `vertex[]`·`edge[]`·`graphpath[]`입니다. 그 밖의 것은 `jsonb`를 만듭니다. {bdg-secondary-line}`2.18에 추가` - 그 타입 그대로의 배열도 `jsonb` 리스트처럼 Cypher의 첨자로 0부터 인덱싱합니다. - null 값도 모읍니다. `collect(DISTINCT expr)`은 중복을 없앱니다. - `length()`는 네 결과 타입 어느 것에 대해서도 요소 개수를 셉니다. ```cypher MATCH (p:person)-[:directed]->(m:movie) WITH p, collect(m.title) AS films RETURN p.name AS director, films ORDER BY p.name LIMIT 2; ``` ``` director | films ---------------------+------------------------------- "Andrew Niccol" | ["Gattaca"] "Christopher Nolan" | ["Inception", "Interstellar"] ``` 그래프 요소 자체를 모으면 그 요소들의 배열이 나옵니다: ```cypher MATCH (:movie {title:'The Matrix'})-[e:related_to]->() WITH collect(e) AS edges RETURN length(edges) AS n, pg_typeof(edges) AS type; ``` ``` n | type ---+---------- 3 | "edge[]" ``` {#aggregate-count} ## count ``` count ( * ) -> bigint count ( expression ) -> bigint ``` 그룹의 행을 셉니다. `count(*)`는 모든 행을 세고, `count(expression)`은 그 표현식이 null이 아닌 행을 셉니다. **고려할 점** - 정점이나 간선 전체에 대한 `count(v)`는 그 요소의 식별자를 셉니다. 파서가 그 인자를 그 `graphid`로 바꾸므로 `properties`는 전혀 읽지 않습니다. - `count(DISTINCT expression)`은 null이 아닌 서로 다른 값을 셉니다. - 행이 없는 그룹은 null이 아니라 0을 반환합니다. ```cypher MATCH (m:movie) RETURN count(*) AS films, count(m.genre) AS with_genre, count(DISTINCT m.genre) AS genres; ``` ``` films | with_genre | genres -------+------------+-------- 18 | 18 | 3 ``` {#aggregate-max} ## max ``` max ( expression jsonb ) -> jsonb max ( expression numeric ) -> numeric ``` 그룹에서 가장 큰 값을 반환합니다. **고려할 점** - `jsonb` 인자는 `jsonb` 자신의 타입 순서로 정렬되며, 그 순서에서는 모든 숫자가 모든 문자열보다 아래에 옵니다. 타입 컬럼에서 읽은 수치·텍스트 속성은 그 컬럼의 타입으로 비교됩니다. - null은 건너뜁니다. null이 아닌 값이 하나도 없는 그룹은 null을 반환합니다. ```cypher MATCH (m:movie) RETURN min(m.year) AS earliest, max(m.year) AS latest; ``` ``` earliest | latest ----------+-------- 1982 | 2021 ``` {#aggregate-min} ## min ``` min ( expression jsonb ) -> jsonb min ( expression numeric ) -> numeric ``` 그룹에서 가장 작은 값을 반환합니다. [`max`](#aggregate-max)의 고려할 점이 그대로 적용됩니다. {#aggregate-percentilecont} ## percentileCont ``` percentileCont ( list jsonb, percentile numeric ) -> double precision ``` 숫자 리스트의 백분위수를 반환하며, 요구한 위치를 사이에 둔 두 값 사이를 보간합니다. **고려할 점** - 이것은 집계 함수가 아니라 리스트에 대한 평범한 함수입니다. 그룹의 백분위수를 구하려면 먼저 리스트를 만드십시오. `percentileCont(collect(m.year), 0.5)`입니다. - 인자는 리스트여야 합니다. 스칼라는 거부되고, 메시지는 엉뚱한 함수를 이름으로 부릅니다: ```cypher RETURN percentileCont(2010, 0.5); ``` ``` ERROR: reverse(): list is expected but 2010 ``` - 리스트에 요소가 둘보다 적거나 백분위수가 0에서 1 범위를 벗어나면 null을 반환합니다. - 숫자가 아닌 요소는 거부되는 것이 아니라 무시됩니다. ```cypher MATCH (m:movie) RETURN percentileCont(collect(m.year), 0.5) AS median; ``` ``` median -------- 2002.5 ``` {#aggregate-percentiledisc} ## percentileDisc ``` percentileDisc ( list jsonb, percentile numeric ) -> double precision ``` 숫자 리스트의 백분위수를 반환하며, 실제로 리스트에 있는 요소로 내림합니다. 고려할 점은 [`percentileCont`](#aggregate-percentilecont)와 같습니다. ```cypher MATCH (m:movie) RETURN percentileDisc(collect(m.year), 0.5) AS median; ``` ``` median -------- 2002 ``` {#aggregate-stdev} ## stdev ``` stdev ( expression numeric ) -> numeric ``` 그룹의 값들의 표본 표준편차를 반환합니다. *n* − 1로 나누는 추정값입니다. **고려할 점** - 파서가 이 이름을 `stddev_samp`로 다시 쓰므로, 결과 컬럼이 지니는 이름과 오류 메시지가 쓰는 이름이 그것입니다. - 따옴표 없는 식별자는 소문자로 접히므로 `stDev`와 `STDEV`는 같은 호출입니다. - `stdDev`는 *다른* 함수입니다. 그것은 `stddev`로 접히고, 그것은 `stddev_samp`에 대한 PostgreSQL 자신의 별칭입니다. 계산되는 값은 같습니다. - 행이 하나인 그룹은 null을 반환합니다. ```cypher MATCH (m:movie) RETURN stdev(m.year) AS sample_sd, stdevp(m.year) AS population_sd; ``` ``` sample_sd | population_sd ---------------------+--------------------- 11.3628508344062724 | 11.0427061006209596 ``` {#aggregate-stdevp} ## stdevp ``` stdevp ( expression numeric ) -> numeric ``` 그룹의 값들의 모표준편차를 반환합니다. *n*으로 나누는 추정값입니다. 파서가 이 이름을 `stddev_pop`으로 다시 쓰며, `stDevP`도 같은 호출입니다. {#aggregate-sum} ## sum ``` sum ( expression numeric ) -> numeric ``` 그룹에서 null이 아닌 값들의 합을 반환합니다. **고려할 점** - null은 건너뜁니다. null이 아닌 값이 하나도 없는 그룹은 0이 아니라 null을 반환합니다. - 입력의 중복을 없애는 것은 없습니다. 패턴이 두 번 일치시킨 값은 두 번 더해집니다. 그것을 원하지 않으면 `sum(DISTINCT expr)`를 쓰십시오. ```cypher MATCH (p:person)-[:acted_in]->(:movie) RETURN sum(p.born) AS born_total; ``` ``` born_total ------------ 49017 ``` {#aggregate-compatibility} ## 호환성 {#aggregate-opencypher} ### openCypher `stDev`와 `stDevP`는 표본 표준편차와 모표준편차에 대한 openCypher의 이름이며, 두 표기 모두 여기서 동작합니다. openCypher의 `percentileCont`와 `percentileDisc`는 행마다 값을 받는 집계 함수입니다. 여기의 것들은 완성된 리스트를 받으므로, openCypher용으로 쓴 쿼리는 첫 인자를 `collect()`로 감싸야 합니다. {#aggregate-isoiec-39075} ### ISO/IEC 39075 `avg`, `count`, `max`, `min`, `stddev_pop`, `stddev_samp`, `sum`이 GQL의 집계 함수이고 표준이 표기하는 대로 표기됩니다. `collect`는 GQL의 `COLLECT` 값 표현식에 대응하며, 그것은 [서브쿼리 표현식](../clauses/subquery-expressions.md)에 문서화돼 있습니다. {#aggregate-see-also} ## 관련 항목 - [모든 함수](all-functions.md) — 모든 함수를 한 표에 - [조건 함수](predicate.md) — `all`, `any`, `none`, `single` - [리스트 함수](list.md) — `collect`가 내놓는 리스트 다루기