MySQL에서 오름차순(ASC) 정렬을 하다 보면 가장 작은 값이 항상 맨 위로 올라옵니다. 하지만 실무에서는 특정 값 이상인 데이터를 먼저 오름차순으로 정렬한 뒤, 그보다 작은 값들이 다시 첫 번째 값으로 "순환(wrap around)"되어 뒤따르도록 정렬해야 하는 경우가 있습니다.
이 글에서는 단일 쿼리만으로 이러한 순환 정렬 효과를 구현하는 방법을 예제와 함께 살펴봅니다.
1. 예제 테이블 생성
먼저 데모용 테이블을 생성합니다.
mysql> create table DemoTable
-> (
-> Value int
-> );
Query OK, 0 rows affected (3.21 sec)
2. 샘플 데이터 삽입
INSERT 명령을 사용해 여러 개의 레코드를 삽입합니다.
mysql> insert into DemoTable values(20);
Query OK, 1 row affected (0.78 sec)
mysql> insert into DemoTable values(40);
Query OK, 1 row affected (0.94 sec)
mysql> insert into DemoTable values(30);
Query OK, 1 row affected (0.41 sec)
mysql> insert into DemoTable values(10);
Query OK, 1 row affected (0.26 sec)
mysql> insert into DemoTable values(90);
Query OK, 1 row affected (0.21 sec)
mysql> insert into DemoTable values(70);
Query OK, 1 row affected (0.49 sec)
mysql> insert into DemoTable values(80);
Query OK, 1 row affected (0.23 sec)
mysql> insert into DemoTable values(9);
Query OK, 1 row affected (0.23 sec)
mysql> insert into DemoTable values(8);
Query OK, 1 row affected (0.38 sec)
3. 전체 레코드 확인
SELECT 문으로 테이블의 모든 레코드를 조회해 봅니다.
mysql> select *from DemoTable;
실행 결과는 다음과 같습니다.
+-------+
| Value |
+-------+
| 20 |
| 40 |
| 30 |
| 10 |
| 90 |
| 70 |
| 80 |
| 9 |
| 8 |
+-------+
9 rows in set (0.00 sec)
4. 순환 정렬 쿼리 실행
아래 쿼리는 Value > 10 조건을 기준으로 내림차순 정렬을 먼저 적용한 후, 같은 그룹 내에서 오름차순 정렬을 수행합니다. 그 결과 10보다 큰 값들이 먼저 오름차순으로 출력되고, 10 이하의 값들은 마지막에 이어서 나타나며 첫 번째 값으로 순환되는 듯한 정렬 효과를 얻을 수 있습니다.
mysql> select *from DemoTable
-> order by Value > 10 desc, Value asc;
실행 결과는 다음과 같습니다.
+-------+
| Value |
+-------+
| 20 |
| 30 |
| 40 |
| 70 |
| 80 |
| 90 |
| 8 |
| 9 |
| 10 |
+-------+
9 rows in set (0.00 sec)
동작 원리 정리
핵심은 ORDER BY 절의 두 가지 조건입니다.
첫 번째 조건 — Value > 10 desc: 불리언(Boolean) 표현식은 MySQL에서 참(TRUE=1) 또는 거짓(FALSE=0)으로 평가됩니다. 내림차순(desc)으로 정렬하기 때문에 TRUE(1)인 행, 즉 10보다 큰 값들이 앞쪽에 배치되고 FALSE(0)인 행은 뒤로 밀려납니다.
두 번째 조건 — Value asc: 각 그룹 내부에서는 오름차순으로 정렬됩니다. 따라서 20, 30, 40, 70, 80, 90 순으로 먼저 출력된 뒤, 8, 9, 10이 뒤따림으로써 마치 목록의 끝에서 시작 부분으로 순환하는 것과 같은 결과가 만들어집니다.
이처럼 불리언 표현식과 다중 정렬 조건을 활용하면 별도의 UNION이나 서브쿼리 없이도 단일 쿼리로 원하는 순환 정렬을 간단하게 구현할 수 있습니다.