GROUP BY + GROUP_CONCAT

호이·2025년 12월 10일

📘 GROUP BY + GROUP_CONCAT 으로 여러 값을 한 행으로 합치기

같은 개체(id, name)가 여러 개의 값을 가지고 있을 때
이를 한 행에 합쳐서 출력하려고 할때 !!

특히 메달, 태그, 카테고리, 옵션 목록처럼 하나의 주체가 여러 값을 가질 수 있는 구조에서 자주 사용된다.
이 글에서는 GROUP BY와 GROUP_CONCAT을 활용해 이 문제를 정리한다.


1. 데이터 구조 (예시)

아래는 단순화한 예시 테이블이다.

participation (
    athlete_id INT,
    medal VARCHAR
)

athlete_info (
    id INT,
    name VARCHAR
)

한 선수가 여러 메달을 가진 상황을 가정하자.

예시 데이터:

athlete_idnamemedal
10Hanabronze
10Hanabronze
10Hanagold
12Seulgisilver

이 경우 원하는 출력 형태는 다음 두 가지 중 하나다.

  1. 중복 포함bronze, bronze, gold
  2. 중복 제거bronze, gold

2. GROUP BY 없이 JOIN만 하면 생기는 문제

처음에 흔히 작성하는 쿼리는 다음 형태다.

SELECT
    a.id,
    a.name,
    p.medal
FROM participation p
JOIN athlete_info a ON p.athlete_id = a.id;

이렇게 하면 메달이 여러 개인 개체는 여러 행으로 출력된다.

idnamemedal
10Hanabronze
10Hanabronze
10Hanagold

원하는 것은 한 행당 한 선수, 즉 “행 집계”다.


3. GROUP BY + GROUP_CONCAT 으로 문자열 집계하기

✔ 중복 포함 버전

SELECT
    a.id,
    a.name,
    GROUP_CONCAT(p.medal ORDER BY p.medal SEPARATOR ', ') AS medals
FROM participation p
JOIN athlete_info a ON p.athlete_id = a.id
GROUP BY a.id, a.name;

출력:

idnamemedals
10Hanabronze, bronze, gold
  • GROUP_CONCAT은 기본적으로 중복을 제거하지 않는다.
  • 원본 데이터의 모든 값이 그대로 나온다.

4. 중복 제거가 필요한 경우 — DISTINCT 추가

중복 없이 종류만 보고 싶은 경우는 DISTINCT를 써야 한다.

✔ 중복 제거 버전

SELECT
    a.id,
    a.name,
    GROUP_CONCAT(DISTINCT p.medal ORDER BY p.medal SEPARATOR ', ') AS medals
FROM participation p
JOIN athlete_info a ON p.athlete_id = a.id
GROUP BY a.id, a.name;

출력:

idnamemedals
10Hanabronze, gold
  • DISTINCT 사용 시 문자열 합치기 전에 중복이 제거된다.

5. MySQL vs PostgreSQL 비교

DB중복 포함중복 제거
MySQLGROUP_CONCAT(p.medal)GROUP_CONCAT(DISTINCT p.medal)
PostgreSQLSTRING_AGG(p.medal, ', ')STRING_AGG(DISTINCT p.medal, ', ')

6. 이번에 정리한 포인트

  • GROUP BY 로 기준이 되는 개체를 한 행으로 묶는다.
  • GROUP_CONCAT 은 여러 값을 문자열로 합치는 데 사용한다.
  • 기본 동작은 중복 포함, 중복 제거는 DISTINCT 필요.
  • 문자열 집계는 실무에서 태그 목록, 옵션 목록 등에서 굉장히 자주 쓰인다.

7. 마무리

단순한 JOIN으로 해결되는 문제처럼 보여도,
여러 값을 한 행에 집계해야 하는 상황은 결국 GROUP BY + GROUP_CONCAT 조합이 가장 깔끔하다.
특히 “중복을 허용할지, 제거할지”를 명확히 구분해 두면 실수할 일이 줄어든다.

profile
호잇

0개의 댓글