MySQL에서 특정 필드 값을 원하는 순서대로 정렬하려면 FIND_IN_SET() 함수를 사용하면 됩니다. 일반적인 오름차순(ASC)이나 내림차순(DESC) 정렬과 달리, 개발자가 직접 지정한 사용자 정의 순서대로 결과를 정렬할 수 있어 상태 값(status) 처리에 매우 유용합니다.
1. 테이블 생성
먼저 예제에 사용할 테이블을 생성해 보겠습니다.
mysql> create table DemoTable677( UserId int NOT NULL AUTO_INCREMENT PRIMARY KEY, UserStatus text ); Query OK, 0 rows affected (1.07 sec)
2. 데이터 삽입
INSERT 명령을 사용해 몇 개의 레코드를 추가합니다.
mysql> insert into DemoTable677(UserStatus) values('BUSY');
Query OK, 1 row affected (0.23 sec)
mysql> insert into DemoTable677(UserStatus) values('AT WORK');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable677(UserStatus) values('OFFLINE');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable677(UserStatus) values('BLOCKED');
Query OK, 1 row affected (0.17 sec)3. 전체 레코드 조회
SELECT 문을 사용해 테이블의 모든 레코드를 확인해 보겠습니다.
mysql> select *from DemoTable677;
실행 결과는 다음과 같습니다.
+--------+------------+ | UserId | UserStatus | +--------+------------+ | 1 | BUSY | | 2 | AT WORK | | 3 | OFFLINE | | 4 | BLOCKED | +--------+------------+ 4 rows in set (0.00 sec)
4. FIND_IN_SET()을 이용한 사용자 정의 정렬
이제 핵심인 쿼리입니다. 아래와 같이 FIND_IN_SET() 함수를 ORDER BY 절과 함께 사용하면, 콤마로 구분된 문자열 목록에 나열된 순서대로 결과가 정렬됩니다.
mysql> select *from DemoTable677 ORDER BY FIND_IN_SET(UserStatus, 'BLOCKED,AT WORK,OFFLINE,BUSY');
실행 결과는 다음과 같습니다.
+--------+------------+ | UserId | UserStatus | +--------+------------+ | 4 | BLOCKED | | 2 | AT WORK | | 3 | OFFLINE | | 1 | BUSY | +--------+------------+ 4 rows in set (0.03 sec)
동작 원리
FIND_IN_SET(찾을_값, 값_목록)은 두 번째 인수로 전달된 콤마 구분 목록에서 첫 번째 인수가 위치한 인덱스(1부터 시작)를 반환합니다. 따라서 위 예제에서는 'BLOCKED'가 1, 'AT WORK'가 2, 'OFFLINE'이 3, 'BUSY'가 4를 반환하며, MySQL은 이 반환값을 기준으로 오름차순 정렬을 수행합니다.
만약 목록에 없는 값이 있다면 FIND_IN_SET()은 0을 반환하므로, 해당 레코드는 가장 앞쪽에 정렬됩니다. 이 경우 목록에 없는 값을 마지막에 배치하고 싶다면 ORDER BY FIND_IN_SET(...) = 0, FIND_IN_SET(...)처럼 조건을 조합하여 활용할 수 있습니다.