프로그래머스 SQL - 70번(다양한 풀이, MAX(COUNT(*)) 안되는 이유)

yeyeyeyeye·2025년 8월 13일
-- 코드를 입력하세요
WITH CNT as(
SELECT p.member_name,
       COUNT(p.member_name) as CNT
FROM member_profile p JOIN rest_review r ON p.member_id=r.member_id 
GROUP BY 1
ORDER BY CNT desc
LIMIT 1
)

SELECT p.member_name,
       r.review_text,
       DATE_FORMAT(r.review_date,'%Y-%m-%d') as REVIEW_DATE
FROM member_profile p 
JOIN rest_review r ON p.member_id=r.member_id
JOIN CNT c ON p.member_name=c.member_name
ORDER BY r.review_date, r.review_text;
--안전한 버전 (동명이인 방지)
WITH cnt AS (
  SELECT p.member_id,
         p.member_name,
         COUNT(*) AS cnt
  FROM member_profile p
  JOIN rest_review r ON p.member_id = r.member_id
  GROUP BY p.member_id, p.member_name
  ORDER BY cnt DESC
  LIMIT 1
)
SELECT p.member_name,
       r.review_text,
       DATE_FORMAT(r.review_date, '%Y-%m-%d') AS review_date
FROM member_profile p
JOIN rest_review r ON p.member_id = r.member_id
JOIN cnt c ON p.member_id = c.member_id
ORDER BY r.review_date ASC, r.review_text ASC;
---동률 모두 포함(윈도우 함수)
WITH counts AS (
  SELECT p.member_id,
         p.member_name,
         COUNT(*) AS cnt
  FROM member_profile p
  JOIN rest_review r ON p.member_id = r.member_id
  GROUP BY p.member_id, p.member_name
),
topper AS (
  SELECT *,
         DENSE_RANK() OVER (ORDER BY cnt DESC) AS rk
  FROM counts
)
SELECT p.member_name,
       r.review_text,
       DATE_FORMAT(r.review_date, '%Y-%m-%d') AS review_date
FROM topper t
JOIN member_profile p ON p.member_id = t.member_id
JOIN rest_review r ON r.member_id = t.member_id
WHERE t.rk = 1
ORDER BY r.review_date ASC, r.review_text ASC;

📌 왜 MAX(COUNT(*))는 안 될까? + 올바른 해결법

SQL 문제를 풀다 보면 “그룹별 개수를 세고, 그 중 최댓값을 찾고 싶다”는 상황이 자주 생긴다.
자연스럽게 MAX(COUNT(*))를 떠올리지만, 이건 SQL 문법상 허용되지 않는다.


1. 왜 안 될까?

❌ 잘못된 시도

SELECT MAX(COUNT(*))
FROM member_profile p
JOIN rest_review r ON p.member_id = r.member_id
GROUP BY p.member_id;
  • COUNT(*) → 그룹 집계 함수

  • MAX() → 또 다른 집계 함수
    ➡ 집계 함수 안에 집계 함수를 직접 중첩할 수 없음.

2. SQL 실행 단계에서의 이유

SQL은 GROUP BY 이후에 그룹별 집계를 한 번만 수행함.
GROUP BY로 각 그룹을 만듦.

각 그룹에 대해 COUNT(*) 같은 집계 함수를 계산.

여기서 나온 값은 SELECT 절의 결과 행이 됨.

이미 집계가 끝난 COUNT(*) 결과를 다시 집계하려면 새로운 SELECT 문에서 다시 집계를 시작해야 함.

3. 올바른 해결법

방법 A: 서브쿼리/CTE로 단계 나누기

WITH counts AS (
  SELECT p.member_id, COUNT(*) AS cnt
  FROM member_profile p
  JOIN rest_review r ON p.member_id = r.member_id
  GROUP BY p.member_id
)
SELECT MAX(cnt) AS max_count
FROM counts;
  • 1단계: 각 회원의 리뷰 개수 집계(cnt)
  • 2단계: 그 중 최댓값 계산(MAX(cnt))

방법 B: 윈도우 함수로 한 번에 (MySQL 8+, PostgreSQL 등)

SELECT p.member_id,
       p.member_name,
       COUNT(*) AS cnt,
       MAX(COUNT(*)) OVER () AS max_count
FROM member_profile p
JOIN rest_review r ON p.member_id = r.member_id
GROUP BY p.member_id, p.member_name;
  • COUNT(*) → 그룹별 집계

  • MAX(...) OVER () → 전체 그룹의 집계 결과 중 최댓값을 윈도우 함수로 계산

4. 기억하기

집계 함수 안에 또 다른 집계 함수는 직접 쓸 수 없다.
→ “중간 집계 결과”를 만든 뒤, 그 결과를 다시 집계하는 2단계 접근이 필요하다.

5. 요약

  • MAX(COUNT(*)) → 불가능
  • 서브쿼리/CTE 사용 → 가능

최신 SQL 엔진에서는 윈도우 함수로 한 번에 처리 가능

-- 가장 보편적인 패턴
SELECT MAX(cnt)
FROM (
  SELECT COUNT(*) AS cnt
  FROM table
  GROUP BY some_column
) t;
profile
안녕하세요? 데이터분석가 되고 싶어요.

0개의 댓글