MySQL에서 하나의 컬럼에 세미콜론(;)으로 구분된 여러 값이 저장되어 있을 때, 그중 특정 값이 포함된 레코드를 찾으려면 FIND_IN_SET() 함수와 REPLACE() 함수를 함께 사용하면 됩니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다.
mysql> create table DemoTable
(
Id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
Value varchar(100)
);
Query OK, 0 rows affected (2.49 sec)2. 샘플 데이터 삽입하기
INSERT 명령을 사용해 세미콜론으로 구분된 값들을 저장합니다.
mysql> insert into DemoTable(Value) values('100;200;300');
Query OK, 1 row affected (0.42 sec)
mysql> insert into DemoTable(Value) values('1;300;400');
Query OK, 1 row affected (0.58 sec)
mysql> insert into DemoTable(Value) values('6;7;8;9;10');
Query OK, 1 row affected (0.29 sec)
mysql> insert into DemoTable(Value) values('1;2;3;4;5');
Query OK, 1 row affected (9.36 sec)
mysql> insert into DemoTable(Value) values('3;8;9;10');
Query OK, 1 row affected (0.46 sec)3. 전체 데이터 확인하기
SELECT 문으로 테이블의 모든 레코드를 조회합니다.
mysql> select *from DemoTable;
실행 결과는 다음과 같습니다.
+----+-------------+ | Id | Value | +----+-------------+ | 1 | 100;200;300 | | 2 | 1;300;400 | | 3 | 6;7;8;9;10 | | 4 | 1;2;3;4;5 | | 5 | 3;8;9;10 | +----+-------------+ 5 rows in set (0.00 sec)
4. 특정 값이 포함된 레코드 찾기
FIND_IN_SET() 함수는 쉼표(,)로 구분된 문자열 목록에서 특정 값을 검색하는 함수입니다. 따라서 REPLACE() 함수로 먼저 세미콜론을 쉼표로 변환한 뒤 FIND_IN_SET()에 전달하면 원하는 값을 찾을 수 있습니다.
다음은 값 목록에서 8이 포함된 레코드를 조회하는 쿼리입니다.
mysql> select *from DemoTable where find_in_set(8, replace(Value, ';', ',')) > 0;
실행 결과는 다음과 같습니다.
+----+------------+ | Id | Value | +----+------------+ | 3 | 6;7;8;9;10 | | 5 | 3;8;9;10 | +----+------------+ 2 rows in set (0.00 sec)
위 결과에서 볼 수 있듯이 Value 컬럼에 '8'이 포함된 두 개의 레코드만 정확하게 반환되었습니다.
참고 사항
FIND_IN_SET()은 지정한 값이 목록 내에 존재하면 해당 위치 인덱스(1부터 시작)를 반환하고, 존재하지 않으면 0을 반환합니다. 따라서 WHERE 절에서 반환값이 0보다 큰지 비교하면 조건에 맞는 레코드만 필터링할 수 있습니다.
다만 이 방식은 REPLACE() 연산 때문에 인덱스를 활용할 수 없어 대용량 데이터에서는 성능이 저하될 수 있습니다. 가능하다면 정규화(Normalization)를 통해 값을 별도 테이블에 행 단위로 저장하는 것이 더 바람직한 설계입니다.