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

MySQL에서 GROUP BY와 HAVING으로 중복 값의 최대 날짜 조회하기

데이터베이스 작업을 하다 보면 중복된 값이 존재하는 행들 중에서 가장 최근(최대) 날짜만 조회해야 하는 경우가 자주 있습니다. 이럴 때는 SQL의 GROUP BY 절과 HAVING 절을 함께 사용하면 간단하게 해결할 수 있습니다.

이번 글에서는 실제 예제를 통해 학생 이름별로 중복된 데이터를 찾고, 각 이름에 해당하는 마감일(DueDate) 중 가장 늦은 날짜를 출력하는 방법을 단계별로 살펴보겠습니다.

1. 예제 테이블 생성

먼저 실습에 사용할 테이블을 생성합니다. 학생 이름(StudentName)과 마감일(DueDate) 두 개의 컬럼으로 구성된 간단한 테이블입니다.

mysql> create table DemoTable
    (
    StudentName varchar(100),
    DueDate date
    );
Query OK, 0 rows affected (0.72 sec)

2. 샘플 데이터 삽입

다음으로 INSERT 명령을 사용해 테이블에 여러 개의 레코드를 추가합니다. 의도적으로 John, Chris, Bob, Robert의 이름이 중복되도록 데이터를 구성했습니다.

mysql> insert into DemoTable values('John','2019-01-11');
Query OK, 1 row affected (0.26 sec)
mysql> insert into DemoTable values('Chris','2019-02-11');
Query OK, 1 row affected (0.20 sec)
mysql> insert into DemoTable values('Chris','2019-03-11');
Query OK, 1 row affected (0.19 sec)
mysql> insert into DemoTable values('John','2019-04-11');
Query OK, 1 row affected (0.12 sec)
mysql> insert into DemoTable values('Bob','2019-05-11');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable values('Bob','2019-06-11');
Query OK, 1 row affected (0.15 sec)
mysql> insert into DemoTable values('Robert','2019-07-11');
Query OK, 1 row affected (0.18 sec)
mysql> insert into DemoTable values('Robert','2019-08-11');
Query OK, 1 row affected (0.17 sec)
mysql> insert into DemoTable values('Robert','2019-09-11');
Query OK, 1 row affected (0.15 sec)

3. 전체 데이터 확인

SELECT 문을 실행해 테이블에 저장된 모든 레코드를 확인해 보겠습니다.

mysql> select *from DemoTable;

출력 결과

+-------------+------------+
| StudentName | DueDate    |
+-------------+------------+
| John        | 2019-01-11 |
| Chris       | 2019-02-11 |
| Chris       | 2019-03-11 |
| John        | 2019-04-11 |
| Bob         | 2019-05-11 |
| Bob         | 2019-06-11 |
| Robert      | 2019-07-11 |
| Robert      | 2019-08-11 |
| Robert      | 2019-09-11 |
+-------------+------------+
9 rows in set (0.00 sec)

출력 결과를 보면 총 9개의 레코드가 있으며, 네 명의 학생 모두 두 번 이상 등장하는 것을 알 수 있습니다.

4. 중복 값과 최대 날짜 조회 쿼리

이제 핵심인 쿼리입니다. 아래 쿼리는 GROUP BY로 학생 이름별로 그룹화한 뒤, HAVING COUNT(*) > 1 조건을 통해 두 번 이상 나타나는(즉, 중복되는) 이름만 필터링하고, MAX() 함수로 각 그룹의 가장 늦은 마감일을 반환합니다.

mysql> select tbl.StudentName,max(tbl.DueDate) from DemoTable tbl group by tbl.StudentName
having count(*) > 1;

출력 결과

+-------------+------------------+
| StudentName | max(tbl.DueDate) |
+-------------+------------------+
| John        | 2019-04-11       |
| Chris       | 2019-03-11       |
| Bob         | 2019-06-11       |
| Robert      | 2019-09-11       |
+-------------+------------------+
4 rows in set (0.00 sec)

정리

실행 결과를 보면 중복된 이름을 가진 4명의 학생이 각각 한 번씩만 출력되었고, 그 옆에는 해당 학생의 마감일 중 가장 최신 날짜가 표시된 것을 확인할 수 있습니다.

핵심 포인트를 정리하면 다음과 같습니다.

  • GROUP BY: 중복 판단 기준이 되는 컬럼(여기서는 StudentName)으로 데이터를 그룹화합니다.
  • HAVING COUNT(*) > 1: 그룹화된 결과 중 레코드 수가 2개 이상인 것, 즉 중복된 값만 남깁니다.
  • MAX(): 각 그룹 내에서 날짜 컬럼의 최대값(가장 최근 날짜)을 추출합니다.

이 패턴은 주문 이력에서 고객별 최근 주문일을 찾거나, 로그 데이터에서 사용자별 마지막 접속일을 집계하는 등 다양한 실무 상황에서 응용할 수 있으니 꼭 기억해 두시기 바랍니다.