배열은 한 컬럼에 여러 값을 저장할 때 자주 써. 예를 들면 태그, 번호, 역할, 선호도 같은 거지. 근데 배열에 내가 원하는 값이 들어있는지, 아니면 반대로 모든 요소가 어떤 조건을 만족하는지 어떻게 알 수 있을까? PostgreSQL은 이런 체크를 쉽게 할 수 있는 ANY, ALL, array_contains() 같은 도구를 제공해. 하나씩 알아보자!
ANY가 뭐야?
예를 들어, 여러 값이 들어있는 배열이 있다고 해보자. 예를 들면 상품 ID, 전화번호, 취미 리스트 같은 거. 종종 배열에 특정 값이 있는지 확인해야 할 때가 있어. 이럴 때 ANY 연산자가 등장하지! 이건 배열에 "내가 찾는 값"이 들어있는지 체크해줘.
ANY 문법
SELECT *
FROM your_table
WHERE value = ANY(array_column);
여기서:
array_column— 우리가 체크할 배열이야.value— 배열에서 찾고 싶은 값이야.
ANY 사용 예시
예를 들어, students라는 테이블이 이렇게 있다고 해보자:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {독서, 수영, 체스} |
| 2 | Eva | {음악, 독서, 스포츠} |
| 3 | Alex | {그리기, 음악} |
| 4 | Maria | {체스, 축구} |
취미 중에 수영이 있는 학생을 찾고 싶으면 이렇게 쿼리하면 돼:
SELECT *
FROM students
WHERE '수영' = ANY(hobbies);
결과:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {독서, 수영, 체스} |
간단히 말해서, ANY는 "이 배열에 이 값이 있냐?"를 체크하는 거야.
믿되, 다 확인하자! ALL 사용하기
이번엔 반대 상황을 생각해보자: 모든 배열 요소가 어떤 규칙을 만족하는지 확인하고 싶을 때가 있어. 이럴 때 PostgreSQL은 ALL 연산자를 제공해. 이걸로 배열의 모든 요소가 특정 값과 같거나, 어떤 숫자보다 크거나, 논리 조건을 다 만족하는지 체크할 수 있어.
ALL 문법
SELECT *
FROM your_table
WHERE value < ALL(array_column);
여기서:
array_column— 우리가 체크할 배열이야.value < ALL(...)는 모든 배열 요소가 value보다 커야 한다는 뜻이야.
다시 students 테이블로 돌아가보자. 예를 들어, 모든 취미가 "독서"로 시작하는 학생을 찾고 싶다고 해보자. 쿼리는 이렇게:
SELECT *
FROM students
WHERE '독서' = ALL(hobbies);
결과는 아무것도 안 나와. 왜냐면 모든 취미가 "독서"인 학생이 없으니까. 좀 더 이해하기 쉬운(그리고 실제로 동작하는) 예시로 숫자 데이터를 생각해보자.
예를 들어, orders라는 테이블이 있다고 해보자:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
| 3 | Alex | {500, 600, 700} |
모든 항목 가격이 400보다 싼 주문을 찾으려면:
SELECT *
FROM orders
WHERE 400 > ALL(prices);
결과:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
배열 내용으로 행 필터링하기
배열에서 데이터 찾는 기본 함수랑 연산자를 알아봤는데, 실제로 어떻게 쓰는지 예시를 더 볼까?
예시 1: 취미 중에 하나라도 음악이 있는 학생 찾기
원본 테이블:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {독서, 음악, 달리기} |
| 2 | Eva | {그리기, 수영} |
| 3 | Maria | {음악, 복싱} |
| 4 | Alex | {축구, 복싱, 보드게임} |
SELECT *
FROM students
WHERE '음악' = ANY(hobbies);
결과:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {독서, 음악, 달리기} |
| 3 | Maria | {음악, 복싱} |
예시 2: 모든 가격이 100보다 큰 주문 찾기
원본 테이블 orders:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 2 | Eva | {50, 120, 130} |
| 3 | Maria | {200, 250, 100} |
| 4 | Alex | {110, 115, 120} |
SELECT *
FROM orders
WHERE 100 < ALL(prices);
결과:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 4 | Alex | {110, 115, 120} |
흔한 실수랑 피하는 방법
배열로 데이터 찾을 때, 특히 초보면 몇 가지 함정이 있어. 조심해야 해!
실수: ANY나 ALL 잘못 쓰기. 예를 들어, 연산자를 헷갈리면 예상치 못한 결과가 나올 수 있어.
-- 잘못된 예시:
SELECT *
FROM students
WHERE hobbies = ANY('독서');
여기서 문제는 hobbies는 배열이고, '독서'는 문자열이야. ANY로 체크할 때는 배열이 오른쪽에 와야 해, 반대로 쓰면 안 돼.
실수: 배열 인덱스가 1부터 시작한다는 점을 모름. 다른 함수에서 배열을 쓰거나 직접 요소를 뽑을 때 PostgreSQL은 인덱스가 1부터 시작하니까 주의!
실수: 인덱싱 안 함. 배열로 ANY, ALL 같은 검색을 자주 하면, 인덱스를 걸어두면 쿼리가 훨씬 빨라질 수 있어.
GO TO FULL VERSION