오늘은 유용하지만 잘 사용되지는 않는 쿼리문 중 하나인
FIND_IN_SET 함수를 소개하고자 합니다.
‘1,2,3’ 처럼 쉼표로 구분된 id값 여러개를 문자열을 담는 1개의 컬럼이 있다고 가정해보자.
그리고, 해당 컬럼 다른 테이블과 조인하여 가져올때, IN 쿼리처럼 사용하고 싶은 경우가 발생할 수 있다.
이런 겨웅 FIND_IN_SET 을 사용하면 해결할 수 있는데, 예제를 통해 구체적인 사용법을 알아보자.
예제 :
예제 테이블 : 상품의 태그기능
# 상품테이블
CREATE TABLE products (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
tags VARCHAR(255) COMMENT '사용중인 태그id 리스트를 문자열로 저장(예시:1,2,3)'
);
# 태그테이블
CREATE TABLE tags (
id INT AUTO_INCREMENT PRIMARY KEY COMMENT '태그id',
tag_name VARCHAR(255) NOT NULL
);
SQL
복사
products 상품 테이블 데이터
id | name | tags |
1 | Product A | 1,2,3 |
2 | Product B | 2,3,4 |
3 | Product C | 3,4,5 |
4 | Product D | 4,5,6 |
5 | Product E | 5,6,7 |
tags 태그 테이블 데이터
id | tag_name |
1 | Electronics |
2 | Home Appliances |
3 | Books |
4 | Toys |
5 | Clothing |
6 | Sports |
7 | Automotive |
위에서 ‘상품’ 테이블에는 ‘tags’ 라는 컬럼이 있고, 여기에 태그의 아이디를 문자열로 등록한다.
즉, ‘product::tags’ 컬럼은 ‘tags::id’ 의 값을 다중 문자열형태로 저장한 것이다.
(물론, product::tags 는 제1정규화를 위배하는 거지만
실무에서는 여러케이스가 있기 때문에 이 부분은 넘어가자.)
여기서 3:Books, 4:Toys 태그를 가진 상품목록을 가져오고 싶다.
결과는 Product A~D 가 나와야 정확하다. (3,4가 포함된)
막상 IN 이나 LIKE 절을 사용해서 해결해보려고 하지만,
깔끔하게 해결되지 않는다.
FIND_IN_SET 사용 :
SELECT p.id AS product_id, p.name AS product_name, p.tags
FROM products p
WHERE EXISTS (
SELECT 1
FROM tags t
WHERE t.tag_name IN ('Books', 'Toys') AND FIND_IN_SET(t.id, p.tags)
);
SQL
복사
이럴 때 FIND_IN_SET 을 사용하여 해결할 수 있다.