MySQL에서 동일한 값이 여러 개 존재할 때 각 그룹별로 특정 행 하나만 가져오고 싶다면 GROUP BY 절을 활용하면 됩니다. 서브쿼리로 먼저 정렬을 수행한 뒤 GROUP BY를 적용하면 원하는 결과를 얻을 수 있습니다.
1. 테이블 생성하기
먼저 예제에 사용할 테이블을 생성합니다.
mysql> create table DemoTable659(Id int, Name varchar(100), Score int);
Query OK, 0 rows affected (0.52 sec)
2. 데이터 삽입하기
INSERT 명령어를 사용해 몇 개의 레코드를 삽입합니다. 이때 'John'이라는 이름이 두 번 등장하도록 의도적으로 중복 값을 넣습니다.
mysql> insert into DemoTable659 values(11,'John',45);
Query OK, 1 row affected (0.14 sec)
mysql> insert into DemoTable659 values(15,'John',59);
Query OK, 1 row affected (0.20 sec)
mysql> insert into DemoTable659 values(15,'Sam',61);
Query OK, 1 row affected (0.14 sec)
3. 전체 레코드 확인하기
SELECT 문으로 테이블의 모든 레코드를 조회해 보겠습니다.
mysql> select *from DemoTable659;
실행 결과는 다음과 같습니다.
+------+------+-------+
| Id | Name | Score |
+------+------+-------+
| 11 | John | 45 |
| 15 | John | 59 |
| 15 | Sam | 61 |
+------+------+-------+
3 rows in set (0.00 sec)
4. 값이 같을 때 특정 행 가져오기
이름(Name)이 중복되는 경우에도 각 이름별로 한 개의 행만 가져오려면 아래와 같은 쿼리를 사용할 수 있습니다. 핵심은 서브쿼리에서 ORDER BY로 정렬한 후, 외부 쿼리에서 GROUP BY를 적용하는 것입니다.
mysql> select *from ( select *from DemoTable659 order by Id desc) tbl group by Name;
위 쿼리의 실행 결과는 다음과 같습니다.
+------+------+-------+
| Id | Name | Score |
+------+------+-------+
| 11 | John | 45 |
| 15 | Sam | 61 |
+------+------+-------+
2 rows in set (0.04 sec)
결과 분석
출력 결과를 보면 'John'은 원래 두 개의 행(Id 11, Id 15)이 있었지만, 정렬 후 GROUP BY가 적용되면서 한 개의 행만 반환된 것을 확인할 수 있습니다. 이처럼 서브쿼리의 ORDER BY와 외부 쿼리의 GROUP BY를 조합하면 중복 값이 있을 때도 원하는 기준에 따라 특정 행 하나씩만 추출할 수 있습니다.
참고로 MySQL 5.7 이상 버전에서는 ONLY_FULL_GROUP_BY SQL 모드가 기본 활성화되어 있어 위 방식이 오류를 일으킬 수 있습니다. 이 경우 윈도우 함수인 ROW_NUMBER()를 사용하는 것이 더 권장되는 방법입니다.