-- 코드를 입력하세요
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 문법상 허용되지 않는다.
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() → 또 다른 집계 함수
➡ 집계 함수 안에 집계 함수를 직접 중첩할 수 없음.
SQL은 GROUP BY 이후에 그룹별 집계를 한 번만 수행함.
GROUP BY로 각 그룹을 만듦.
각 그룹에 대해 COUNT(*) 같은 집계 함수를 계산.
여기서 나온 값은 SELECT 절의 결과 행이 됨.
이미 집계가 끝난 COUNT(*) 결과를 다시 집계하려면 새로운 SELECT 문에서 다시 집계를 시작해야 함.
방법 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;
방법 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 () → 전체 그룹의 집계 결과 중 최댓값을 윈도우 함수로 계산
집계 함수 안에 또 다른 집계 함수는 직접 쓸 수 없다.
→ “중간 집계 결과”를 만든 뒤, 그 결과를 다시 집계하는 2단계 접근이 필요하다.
최신 SQL 엔진에서는 윈도우 함수로 한 번에 처리 가능
-- 가장 보편적인 패턴
SELECT MAX(cnt)
FROM (
SELECT COUNT(*) AS cnt
FROM table
GROUP BY some_column
) t;