배열 함수와 연산자
배열 함수와 연산자 (Array Functions and Operators)
PostgreSQL의 배열 타입은 값 여러 개를 한 컬럼에 담을 수 있어서 유용한데, 이 배열을 다루는 연산자와 함수도 꽤 풍부해요. 포함 관계를 확인하거나, 여러 배열을 이어붙이거나, 요소를 검색·변경하는 일을 어떻게 하는지 정리해 볼게요.
출처: 공식문서
배열 연산자
범용 비교 연산자(Table 9.1)도 배열에 그대로 쓸 수 있어요. 배열의 비교 연산자는 요소 타입의 기본 B-tree 비교 함수로 요소를 하나씩 비교하고, 처음 달라지는 지점을 기준으로 정렬해요. 다차원 배열에서는 행 우선 순서(row-major order, 마지막 첨자가 가장 빨리 변하는 순서)로 요소를 방문해요. 두 배열의 내용이 같아도 차원이 다르면, 차원 정보에서 처음 달라지는 지점이 정렬 순서를 결정해요.
| 연산자 | 설명 | 예시 |
|---|---|---|
anyarray @> anyarray → boolean |
첫 배열이 두 번째 배열을 포함하는지, 즉 두 번째 배열의 각 요소가 첫 배열의 어떤 요소와 같은지 확인해요. (중복은 특별히 취급하지 않아서, ARRAY[1] 과 ARRAY[1,1] 은 서로를 포함한다고 간주해요.) |
ARRAY[1,4,3] @> ARRAY[3,1,3] → t |
anyarray <@ anyarray → boolean |
첫 배열이 두 번째 배열에 포함되는지 확인해요. | ARRAY[2,2,7] <@ ARRAY[1,7,4,2,6] → t |
anyarray && anyarray → boolean |
두 배열이 겹치는지, 즉 공통 요소를 갖는지 확인해요. | ARRAY[1,4,3] && ARRAY[2,1] → t |
anycompatiblearray || anycompatiblearray → anycompatiblearray |
두 배열을 이어붙여요. NULL이거나 빈 배열을 붙이면 아무 일도 일어나지 않고, 그 외에는 두 배열의 차원 수가 같거나(첫 예시) 차원 수가 하나 달라야 해요(둘째 예시). 요소 타입이 같지 않으면 공통 타입으로 강제 변환돼요. | ARRAY[1,2,3] || ARRAY[4,5,6,7] → {1,2,3,4,5,6,7} / ARRAY[1,2,3] || ARRAY[[4,5,6],[7,8,9.9]] → {{1,2,3},{4,5,6},{7,8,9.9}} |
anycompatible || anycompatiblearray → anycompatiblearray |
배열(빈 배열 또는 1차원이어야 함)의 앞에 요소를 이어붙여요. | 3 || ARRAY[4,5,6] → {3,4,5,6} |
anycompatiblearray || anycompatible → anycompatiblearray |
배열(빈 배열 또는 1차원이어야 함)의 끝에 요소를 이어붙여요. | ARRAY[4,5,6] || 7 → {4,5,6,7} |
배열 함수
배열 함수는 표(Table 9.57)에 정리돼 있는데, 내용은 아래와 같아요. SQL 함수명과 시그니처·예시는 원문 그대로 두고 설명만 풀어볼게요.
추가·연결·조작
array_append ( anycompatiblearray, anycompatible ) → anycompatiblearray— 배열 끝에 요소를 추가해요. (anycompatiblearray || anycompatible연산자와 같아요.) 예:array_append(ARRAY[1,2], 3)→{1,2,3}array_cat ( anycompatiblearray, anycompatiblearray ) → anycompatiblearray— 두 배열을 연결해요. (||연산자와 동일.) 예:array_cat(ARRAY[1,2,3], ARRAY[4,5])→{1,2,3,4,5}array_prepend ( anycompatible, anycompatiblearray ) → anycompatiblearray— 배열 앞에 요소를 추가해요. 예:array_prepend(1, ARRAY[2,3])→{1,2,3}array_reverse ( anyarray ) → anyarray— 배열의 첫 번째 차원을 뒤집어요. 예:array_reverse(ARRAY[[1,2],[3,4],[5,6]])→{{5,6},{3,4},{1,2}}array_shuffle ( anyarray ) → anyarray— 배열의 첫 번째 차원을 무작위로 섞어요. 예:array_shuffle(ARRAY[[1,2],[3,4],[5,6]])→{{5,6},{1,2},{3,4}}array_sample ( array anyarray, n integer ) → anyarray—array에서 무작위로n개 항목을 뽑은 배열을 반환해요.n은 첫 번째 차원의 길이를 초과할 수 없어요. 배열이 다차원이면 "항목"은 첫 번째 첨자가 정해진 슬라이스예요. 예:array_sample(ARRAY[1,2,3,4,5,6], 3)→{2,6,1}array_sort ( array anyarray [, descending boolean [, nulls_first boolean ]] ) → anyarray— 배열의 첫 번째 차원을 정렬해요. 기본 정렬 순서는 요소 타입의 기본 정렬을 따르고, 요소 타입이 collatable이면array인자에COLLATE절을 붙여 콜레이션을 지정할 수 있어요.descending이 true면 내림차순, 생략하면 오름차순이 기본이에요.nulls_first가 true면 null이 앞에, 아니면 뒤에 와요. 생략하면nulls_first는descending과 같은 값으로 간주돼요. 예:array_sort(ARRAY[[2,4],[2,1],[6,5]])→{{2,1},{2,4},{6,5}}trim_array ( array anyarray, n integer ) → anyarray— 마지막n개 요소를 제거해 배열을 잘라내요. 다차원이면 첫 번째 차원만 잘려요. 예:trim_array(ARRAY[1,2,3,4,5,6], 2)→{1,2,3,4}
차원 정보·생성
array_dims ( anyarray ) → text— 배열 차원의 텍스트 표현을 반환해요. 예:array_dims(ARRAY[[1,2,3], [4,5,6]])→[1:2][1:3]array_fill ( anyelement, integer[] [, integer[] ] ) → anyarray— 주어진 값을 복사해서 채운 배열을 반환하는데, 두 번째 인자가 지정한 길이를 차원으로 가져요. 세 번째(선택) 인자는 각 차원의 하한값을 주고, 기본은 전부1이에요. 예:array_fill(11, ARRAY[2,3])→{{11,11,11},{11,11,11}},array_fill(7, ARRAY[3], ARRAY[2])→[2:4]={7,7,7}array_length ( anyarray, integer ) → integer— 요청한 배열 차원의 길이를 반환해요. 빈 배열이나 없는 차원에서는 0이 아니라NULL을 돌려줘요. 예:array_length(array[1,2,3], 1)→3,array_length(array[]::int[], 1)→NULLarray_lower ( anyarray, integer ) → integer— 요청한 배열 차원의 하한을 반환해요. 예:array_lower('[0:2]={1,2,3}'::integer[], 1)→0array_ndims ( anyarray ) → integer— 배열의 차원 수를 반환해요. 예:array_ndims(ARRAY[[1,2,3], [4,5,6]])→2array_upper ( anyarray, integer ) → integer— 요청한 배열 차원의 상한을 반환해요. 예:array_upper(ARRAY[1,8,3,7], 1)→4cardinality ( anyarray ) → integer— 배열의 총 요소 수를 반환하고, 빈 배열이면 0이에요. 예:cardinality(ARRAY[[1,2],[3,4]])→4
검색·변경·변환
array_position ( anycompatiblearray, anycompatible [, integer ] ) → integer— 배열에서 두 번째 인자가 처음 나타나는 첨자를 반환해요. 없으면NULL이에요. 세 번째 인자가 주어지면 그 첨자부터 검색하고, 배열은 1차원이어야 해요. 비교는IS NOT DISTINCT FROM의미론이라NULL도 찾을 수 있어요. 예:array_position(ARRAY['sun','mon','tue','wed','thu','fri','sat'], 'mon')→2array_positions ( anycompatiblearray, anycompatible ) → integer[]— 첫 배열에서 두 번째 인자가 나타나는 모든 첨자의 배열을 반환해요. 배열은 1차원이어야 하고, 비교는IS NOT DISTINCT FROM의미론이라NULL도 검색 가능해요.NULL은 배열 자체가NULL일 때만 반환되고, 값을 찾지 못하면 빈 배열을 돌려줘요. 예:array_positions(ARRAY['A','A','B','A'], 'A')→{1,2,4}array_remove ( anycompatiblearray, anycompatible ) → anycompatiblearray— 주어진 값과 같은 모든 요소를 배열에서 제거해요. 배열은 1차원이어야 하고,IS NOT DISTINCT FROM의미론이라NULL도 제거할 수 있어요. 예:array_remove(ARRAY[1,2,3,2], 2)→{1,3}array_replace ( anycompatiblearray, anycompatible, anycompatible ) → anycompatiblearray— 두 번째 인자와 같은 각 배열 요소를 세 번째 인자로 교체해요. 예:array_replace(ARRAY[1,2,5,4], 5, 3)→{1,2,3,4}array_to_string ( array anyarray, delimiter text [, null_string text ] ) → text— 각 배열 요소를 텍스트 표현으로 바꿔delimiter문자열로 구분해 이어붙여요.null_string이 주어지고NULL이 아니면NULL배열 항목을 그 문자열로 표현하고, 그렇지 않으면 생략해요.string_to_array도 함께 참고하세요. 예:array_to_string(ARRAY[1, 2, 3, NULL, 5], ',', '*')→1,2,3,*,5
행으로 펼치기
unnest ( anyarray ) → setof anyelement— 배열을 행의 집합으로 펼쳐요. 요소는 저장 순서대로 읽혀요. 예:unnest(ARRAY[1,2])→1,2,unnest(ARRAY[['foo','bar'],['baz','quux']])→foo,bar,baz,quuxunnest ( anyarray, anyarray [, ... ] ) → setof anyelement, anyelement [, ... ]— 여러 (가능하면 다른 타입의) 배열을 행의 집합으로 펼쳐요. 배열 길이가 서로 다르면 짧은 쪽을NULL로 채워요. 이 형태는 쿼리의FROM절에서만 사용할 수 있어요. 예:select * from unnest(ARRAY[1,2], ARRAY['foo','bar','baz']) as x(a,b)→a | b ---+----- 1 | foo 2 | bar | baz
배열과 함께 쓰는 집계 함수 array_agg 는 집계 함수 섹션에서 함께 살펴볼게요.