Computer >> 컴퓨터 >  >> 프로그래밍 >> MySQL

MySQL 하위 쿼리를 활용해 테이블에서 두 번째로 큰 값 조회하는 방법

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가 반드시 필요하며, 상황에 따라 하위 쿼리 방식이 더 명확하고 안전할 수 있습니다.