MySQL에서 테이블에 저장된 값 중 두 번째로 큰 값(최댓값을 제외한 최대값)을 조회해야 하는 경우가 자주 있습니다. 이럴 때 하위 쿼리(Subquery)를 활용하면 간단하게 해결할 수 있습니다. 아래에서 예제 테이블 생성부터 쿼리 작성까지 단계별로 살펴보겠습니다.
1. 예제 테이블 생성하기
먼저 점수를 저장할 테이블을 생성합니다.
mysql> create table DemoTable(
Marks int
);
Query OK, 0 rows affected (1.34 sec)
2. 샘플 데이터 삽입하기
INSERT 명령을 사용해 테이블에 여러 개의 점수를 입력합니다.
mysql> insert into DemoTable values(78);
Query OK, 1 row affected (0.16 sec)
mysql> insert into DemoTable values(88);
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable values(67);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable values(76);
Query OK, 1 row affected (0.25 sec)
mysql> insert into DemoTable values(98);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable values(86);
Query OK, 1 row affected (0.11 sec)
mysql> insert into DemoTable values(89);
Query OK, 1 row affected (0.13 sec)
mysql> insert into DemoTable values(99);
Query OK, 1 row affected (0.12 sec)
3. 전체 데이터 확인하기
SELECT 문을 사용해 테이블에 저장된 모든 레코드를 조회합니다.
mysql> select *from DemoTable;
실행 결과는 다음과 같습니다.
+-------+
| Marks |
+-------+
| 78 |
| 88 |
| 67 |
| 76 |
| 98 |
| 86 |
| 89 |
| 99 |
+-------+
8 rows in set (0.00 sec)
4. 두 번째로 큰 값 조회하는 쿼리
이제 하위 쿼리를 사용해 두 번째로 큰 점수를 조회하는 방법을 살펴보겠습니다. 핵심 아이디어는 다음과 같습니다.
- 가장 안쪽 하위 쿼리가 테이블 전체의 최댓값(MAX)을 구합니다.
- 중간 하위 쿼리는 최댓값보다 작은 값들 중에서 다시 최댓값을 구합니다. 즉, 두 번째로 큰 값이 됩니다.
- 바깥쪽 쿼리는 해당 값과 일치하는 레코드를 최종적으로 반환합니다.
mysql> select Marks from DemoTable
where Marks=(select MAX(Marks) from DemoTable where Marks < (select MAX(Marks) from DemoTable));
실행 결과는 다음과 같습니다.
+-------+
| Marks |
+-------+
| 98 |
+-------+
1 row in set (0.03 sec)
쿼리 동작 원리 정리
위 예제에서 테이블의 최댓값은 99입니다. 중간 하위 쿼리는 99보다 작은 값들(78, 88, 67, 76, 98, 86, 89) 중에서 최댓값인 98을 반환하므로, 최종 결과로 두 번째로 큰 값인 98이 출력됩니다.
이 방식은 중복된 최댓값이 존재하더라도 정확하게 두 번째로 큰 고유값을 찾아낼 수 있다는 장점이 있습니다. 예를 들어 99가 두 개 저장되어 있어도 결과는 여전히 98이 됩니다.
참고: LIMIT와 OFFSET을 사용하는 대안
하위 쿼리 외에도 ORDER BY와 LIMIT, OFFSET을 조합하면 같은 결과를 얻을 수 있습니다.
mysql> select DISTINCT Marks from DemoTable
order by Marks desc limit 1 offset 1;
다만 이 방법은 값의 중복 처리를 위해 DISTINCT가 반드시 필요하며, 상황에 따라 하위 쿼리 방식이 더 명확하고 안전할 수 있습니다.