MySQL에서 IN 조건을 사용해 여러 개의 ID를 조회하면, 결과 집합은 지정한 값의 순서와 상관없이 반환됩니다. 하지만 실무에서는 조회 대상 ID를 나열한 순서 그대로 결과를 정렬해야 하는 경우가 종종 있습니다.
이럴 때 유용한 것이 바로 FIND_IN_SET() 함수입니다. 이 글에서는 FIND_IN_SET()과 ORDER BY 절을 조합해 원하는 순서대로 결과 집합을 만드는 방법을 예제와 함께 단계별로 살펴보겠습니다.
1. 샘플 테이블 생성하기
먼저 학생 정보를 저장할 테이블을 생성합니다.
mysql> create table DemoTable1563 -> ( -> StudentId int, -> StudentName varchar(20) -> ); Query OK, 0 rows affected (0.52 sec)
2. 샘플 데이터 삽입하기
INSERT 문을 사용해 테스트용 레코드를 추가합니다.
mysql> insert into DemoTable1563 values(1001,'Chris'); Query OK, 1 row affected (0.11 sec) mysql> insert into DemoTable1563 values(1010,'Bob'); Query OK, 1 row affected (0.15 sec) mysql> insert into DemoTable1563 values(1005,'Chris'); Query OK, 1 row affected (0.20 sec) mysql> insert into DemoTable1563 values(1015,'David'); Query OK, 1 row affected (0.10 sec) mysql> insert into DemoTable1563 values(1030,'Mike'); Query OK, 1 row affected (0.18 sec) mysql> insert into DemoTable1563 values(1020,'Sam'); Query OK, 1 row affected (0.14 sec)
3. 테이블의 전체 레코드 확인하기
SELECT 문으로 저장된 모든 데이터를 조회합니다.
mysql> select * from DemoTable1563;
위 쿼리는 다음과 같은 출력을 생성합니다.
+-----------+-------------+ | StudentId | StudentName | +-----------+-------------+ | 1001 | Chris | | 1010 | Bob | | 1005 | Chris | | 1015 | David | | 1030 | Mike | | 1020 | Sam | +-----------+-------------+ 6 rows in set (0.00 sec)
4. FIND_IN_SET()으로 지정한 순서대로 정렬하기
다음은 WHERE 절의 IN 조건과 ORDER BY 절의 FIND_IN_SET()을 함께 사용해, ID 목록에 나열된 순서 그대로 결과를 가져오는 쿼리입니다.
mysql> select * from DemoTable1563 -> where StudentId IN(1001,1030,1010,1020) -> order by find_in_set(StudentId,'1001,1030,1010,1020');
위 쿼리는 다음과 같은 출력을 생성합니다.
+-----------+-------------+ | StudentId | StudentName | +-----------+-------------+ | 1001 | Chris | | 1030 | Mike | | 1010 | Bob | | 1020 | Sam | +-----------+-------------+ 4 rows in set (0.00 sec)
동작 원리 이해하기
FIND_IN_SET(찾을_값, 문자열_목록)은 두 번째 인자인 쉼표로 구분된 목록에서 첫 번째 인자가 몇 번째 위치에 있는지를 숫자로 반환합니다. 예를 들어 FIND_IN_SET(1001, '1001,1030,1010,1020')은 1을, FIND_IN_SET(1030, ...)은 2를 반환하는 식입니다.
따라서 ORDER BY 절에서 이 함수를 사용하면 각 행이 목록 내에서 차지하는 위치를 기준으로 정렬되며, 그 결과 ID 목록에 작성한 순서(1001 → 1030 → 1010 → 1020)와 동일한 순서로 결과 집합이 반환됩니다.
주의할 점은 IN 조건에는 있지만 FIND_IN_SET 목록에는 없는 값이 있다면 해당 함수가 0을 반환해 맨 앞쪽에 정렬될 수 있으므로, 두 목록을 항상 동일하게 유지하는 것이 좋습니다.