프로그래머스 SQL - 55번(group by, having, 서브쿼리)

yeyeyeyeye·2025년 7월 29일

꼭 서브쿼리를 써야 할까? GROUP BY + HAVING으로 충분했던 SQL 문제 풀이

SQL 문제를 풀다 보면 "이럴 땐 반드시 서브쿼리를 써야 하나?" 하는 고민을 자주 한다.
이번에 중고 거래 게시글 데이터를 다루면서 그런 고민을 했고,
결과적으로는 GROUP BY + HAVING만으로도 문제를 깔끔하게 해결할 수 있었다.


🧩 문제 상황

중고 거래 게시글(used_goods_board) 테이블에서
게시글을 3건 이상 등록한 사용자user_id, nickname, 전체 주소, 전화번호를 조회하라.

  • 주소는 city, street_address1, street_address2를 이어붙여 출력
  • 전화번호는 tlno 컬럼을 XXX-XXXX-XXXX 형식으로 가공

처음에는 서브쿼리를 생각했다

SELECT user_id, nickname, "전체 주소", "전화번호"
FROM (
    SELECT u.user_id,
           u.nickname,
           CONCAT(u.city, ' ', u.street_address1, ' ', u.street_address2) AS "전체 주소",
           CONCAT(SUBSTR(u.tlno,1,3), '-', SUBSTR(u.tlno,4,4), '-', SUBSTR(u.tlno,8,4)) AS "전화번호",
           COUNT(b.writer_id) AS post_count
    FROM used_goods_board b 
    INNER JOIN used_goods_user u ON b.writer_id = u.user_id
    GROUP BY 1,2,3,4
) sub
WHERE post_count >= 3;

의도: 먼저 집계한 뒤 WHERE로 필터링
단점: 쿼리가 다소 복잡해지고, 굳이 COUNT를 출력할 필요는 없는데 출력하고 있음


💡 그런데 아래와 같이 풀면 GROUP BY + HAVING만으로도 충분했다!

SELECT u.user_id,
       u.nickname,
       CONCAT(u.city, ' ', u.street_address1, ' ', u.street_address2) AS "전체 주소",
       CONCAT(SUBSTR(u.tlno,1,3), '-', SUBSTR(u.tlno,4,4), '-', SUBSTR(u.tlno,8,4)) AS "전화번호"
FROM used_goods_board b 
INNER JOIN used_goods_user u ON b.writer_id = u.user_id
GROUP BY 1,2,3,4
HAVING COUNT(b.writer_id) >= 3;

훨씬 직관적이고 간단한 쿼리

GROUP BY에 포함된 컬럼만 SELECT로 출력

HAVING절을 이용해 집계 조건만 필터링


✅ 핵심 요약
집계 전에 필터링해야 할 조건: WHERE
집계 후 그룹별로 필터링할 조건: HAVING
SELECT에 집계 결과가 필요하지 않을 때: 집계함수(ex.count) 없이도 HAVING만 사용 가능

📌 배운 점
GROUP BY는 반드시 COUNT, SUM 같은 집계함수를 SELECT절에 포함시킬 필요는 없다.

HAVING절은 집계된 결과를 필터링할 때 사용하는 구문이다.

불필요하게 서브쿼리를 쓰는 것보다, 직관적인 GROUP BY + HAVING 구조로 해결하는 것이 더 깔끔하고 효율적일 수 있다.

profile
안녕하세요? 데이터분석가 되고 싶어요.

0개의 댓글