CodeGym /행동 /SQL SELF /배열 비교와 필터링: =, @>, <@, &&

배열 비교와 필터링: =, @>, <@, &&

SQL SELF
레벨 36, 레슨 1
사용 가능

가끔 어떤 값들의 집합이 다른 집합에 포함되는지, 겹치는 게 있는지, 완전히 같은지, 아니면 서로의 부분집합인지 확인해야 할 때가 있어. 예를 들면:

  • 유저가 특정 카테고리에 접근 권한이 있는지?
  • 어떤 상품들이 공통 태그를 가지고 있는지?
  • 어떤 배열이 모든 지정된 값을 포함하는지?

이런 문제들은 PostgreSQL의 배열 비교 연산자 =, @>, <@, &&로 해결할 수 있어. 각각의 연산자를 예제와 함께 살펴보자.

= — 배열이 완전히 같은지 비교

이 연산자는 두 배열이 완전히 똑같은지 확인할 때 써. 두 배열의 길이와 요소 순서, 값이 모두 같아야 TRUE가 나와.

예시:

SELECT ARRAY[1, 2, 3] = ARRAY[1, 2, 3] AS are_equal;  -- TRUE
SELECT ARRAY[1, 2, 3] = ARRAY[3, 2, 1] AS are_equal;  -- FALSE

특징: 요소의 순서가 중요해. [1, 2, 3]은 [3, 2, 1]이랑 다르다고 나와.

@> — 배열이 다른 배열을 포함하는지

이 연산자는 한 배열이 다른 배열의 모든 요소를 포함하는지(순서는 상관없음) 확인해. 찾고 싶은 값들이 전부 들어있는지 체크할 때 자주 써.

예시:

SELECT ARRAY[1, 2, 3] @> ARRAY[1, 2] AS contains;  -- TRUE
SELECT ARRAY[1, 2, 3] @> ARRAY[4] AS contains;     -- FALSE

유용한 상황: 권한 체크할 때 좋아. 예를 들어, 어떤 역할(role)이 필요한 모든 권한을 갖고 있는지 확인할 때 쓸 수 있어.

<@ — 배열이 다른 배열의 부분집합인지

@>의 반대야. 한 배열이 다른 배열에 완전히 포함되어 있는지 확인해.

예시:

SELECT ARRAY[1, 2] <@ ARRAY[1, 2, 3] AS is_subset;  -- TRUE
SELECT ARRAY[4] <@ ARRAY[1, 2, 3] AS is_subset;     -- FALSE

유용한 상황: 테이블의 특정 행이 모든 필요한 태그나 카테고리를 갖고 있는지 확인할 때 쓸 수 있어.

&& — 배열이 겹치는지(교집합)

이 연산자는 두 배열이 하나라도 같은 요소를 갖고 있는지 확인해.

예시:

SELECT ARRAY[1, 2, 3] && ARRAY[3, 4, 5] AS intersects;  -- TRUE
SELECT ARRAY[1, 2, 3] && ARRAY[6, 7, 8] AS intersects;  -- FALSE

유용한 상황: 공통 카테고리나 특징을 가진 상품이나 레코드를 찾을 때 좋아.

데이터 필터링에 연산자 사용하기

이제 이 연산자들을 테이블 데이터 필터링에 써보자. 예를 들어, products라는 테이블에 각 상품의 태그 배열을 담은 tags 컬럼이 있다고 해보자.

products 테이블 예시

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}
4 "Product D" {home, garden}

electronics 태그가 있는 상품을 찾아보자.

SELECT *
FROM products
WHERE tags @> ARRAY['electronics'];

결과:

id name tags
1 "Product A" {electronics, sale}
3 "Product C" {electronics, new}

태그가 정확히 {home, sale}인 상품을 찾고 싶어.

SELECT *
FROM products
WHERE tags = ARRAY['home', 'sale'];

결과:

id name tags
2 "Product B" {home, sale}

이번엔

{sale, new} 중 하나라도 태그에 있는 상품을 찾아보자.
SELECT *
FROM products
WHERE tags && ARRAY['sale', 'new'];

결과:

id name tags
1 "Product A" {electronics, sale}
2 "Product B" {home, sale}
3 "Product C" {electronics, new}

태그가 정확히 {home, garden}으로만 제한된 상품을 찾아보자.

SELECT *
FROM products
WHERE tags <@ ARRAY['home', 'garden'];

결과:

id name tags
4 "Product D" {home, garden}

예시: CASE로 리스트 내용 체크하기

배열 비교를 조건문이랑 같이 쓸 수도 있어. 예를 들어, sale 태그가 있으면 "할인", 없으면 "할인 없음"으로 표시하는 쿼리를 만들어보자:

SELECT name,
       CASE
         WHEN tags @> ARRAY['sale'] THEN '할인'
         ELSE '할인 없음'
       END AS discount_status
FROM products;

결과:

name discount_status
"Product A" 할인
"Product B" 할인
"Product C" 할인 없음
"Product D" 할인 없음

흔한 실수와 예방법

실수: = 연산자에서 요소 순서를 잘못 쓴 경우. =는 요소 순서까지 완전히 같아야 해. 순서가 중요하지 않으면 @>나 &&를 써.

실수: 데이터 타입이 안 맞는 경우. 배열끼리 타입이 같아야 해. 예를 들어, ARRAY['1', '2']는 ARRAY[1, 2]랑 다르지. 앞은 문자열 배열, 뒤는 숫자 배열이니까. 비교 전에 항상 타입을 체크해.

실수: 인덱스가 없는 경우. 배열로 자주 필터링한다면 성능을 위해 꼭 GIN 인덱스를 만들어줘.

이런 연산자들을 잘 쓰면 실제 프로젝트에서 자주 나오는 데이터 필터링과 비교를 쉽게 할 수 있어. 예를 들어 상품 태그 분석이나 권한 관리 같은 거 말이야. 잘 활용하면 복잡한 문제도 간단하게 풀고 쿼리 성능도 확 올릴 수 있어!

2
과제
SQL SELF, 레벨 36, 레슨 1
잠금
배열의 내용을 `@>` 연산자로 확인하기
배열의 내용을 `@>` 연산자로 확인하기
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION