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

MySQL GROUP BY 절에서 행을 정렬하고 선택하는 방법 완벽 가이드

개요

MySQL에서 GROUP BY 절을 사용할 때 각 그룹에서 특정 행을 선택하거나 정렬해야 하는 경우가 자주 발생합니다. 이 글에서는 서브쿼리와 MIN() 함수를 활용하여 그룹별로 원하는 행을 효과적으로 추출하는 방법을 단계별로 살펴보겠습니다.

1. 예제 테이블 생성하기

먼저 실습에 사용할 테이블을 생성합니다.

mysql> create table DemoTable1572
    -> (
    -> StudentId int,
    -> StudentMarks int,
    -> StudentName varchar(20)
    -> );
Query OK, 0 rows affected (0.56 sec)

2. 샘플 데이터 삽입하기

INSERT 명령어를 사용해 테이블에 학생 데이터를 입력합니다.

mysql> insert into DemoTable1572 values(1,79,'Sam');
Query OK, 1 row affected (0.10 sec)
mysql> insert into DemoTable1572 values(2,89,'Chris');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable1572 values(3,98,'David');
Query OK, 1 row affected (0.22 sec)
mysql> insert into DemoTable1572 values(4,79,'Bob');
Query OK, 1 row affected (0.10 sec)

3. 전체 데이터 조회하기

SELECT 문으로 테이블의 모든 레코드를 확인합니다.

mysql> select * from DemoTable1572;

실행 결과는 다음과 같습니다.

+-----------+--------------+-------------+
| StudentId | StudentMarks | StudentName |
+-----------+--------------+-------------+
|         1 |           79 |         Sam |
|         2 |           89 |       Chris |
|         3 |           98 |       David |
|         4 |           79 |         Bob |
+-----------+--------------+-------------+
4 rows in set (0.00 sec)

4. GROUP BY로 그룹별 행 선택하기

여기서 핵심은 동일한 점수(StudentMarks)를 가진 학생들 중 가장 작은 StudentId를 가진 행만 선택하는 것입니다. Sam(79점)과 Bob(79점)은 같은 그룹에 속하므로, 이 중 StudentId가 더 작은 Sam만 결과에 포함됩니다.

아래 쿼리는 GROUP BYMIN()을 조합한 서브쿼리를 사용하여 이를 구현합니다.

mysql> select * from DemoTable1572
    -> where StudentId in (select min(StudentId) from DemoTable1572 group by StudentMarks);

실행 결과는 다음과 같습니다.

+-----------+--------------+-------------+
| StudentId | StudentMarks | StudentName |
+-----------+--------------+-------------+
|         1 |           79 |         Sam |
|         2 |           89 |       Chris |
|         3 |           98 |       David |
+-----------+--------------+-------------+
3 rows in set (0.10 sec)

쿼리 동작 원리 설명

이 쿼리가 어떻게 동작하는지 내부적으로 살펴보겠습니다.

  • 내부 서브쿼리: select min(StudentId) from DemoTable1572 group by StudentMarks는 점수별로 학생들을 그룹화한 후, 각 그룹에서 가장 작은 StudentId 값을 반환합니다. 즉, 79점 그룹에서는 1(Sam), 89점 그룹에서는 2(Chris), 98점 그룹에서는 3(David)이 선택됩니다.
  • 외부 쿼리: WHERE StudentId IN (...) 조건을 통해 해당 ID를 가진 행만 최종 결과로 출력합니다.

참고 사항

만약 각 그룹에서 가장 큰 StudentId를 선택하고 싶다면 MIN() 대신 MAX() 함수를 사용하면 됩니다. 또한 MySQL 8.0 이상에서는 윈도우 함수(Window Function)ROW_NUMBER() OVER (PARTITION BY ...)를 활용하면 더 유연하게 그룹별 첫 번째 또는 마지막 행을 선택할 수 있습니다.

마무리

이처럼 GROUP BY 절과 집계 함수, 서브쿼리를 조합하면 그룹화된 데이터 중에서 원하는 행을 손쉽게 정렬하고 선택할 수 있습니다. 실무에서 중복 데이터 제거나 그룹별 대표 값 추출 시 매우 유용하게 활용되는 패턴이니 꼭 익혀두시기 바랍니다.