https://school.programmers.co.kr/learn/courses/30/lessons/133027
SELECT F.FLAVOR FROM FIRST_HALF AS F
JOIN JULY AS J ON F.FLAVOR = J.FLAVOR
GROUP BY F.FLAVOR
ORDER BY F.TOTAL_ORDER + SUM(J.TOTAL_ORDER) DESC LIMIT 3
- FIRST_HALF는 FLAVOR가 기본키라서 맛당 1행이다
- JULY는 같은 맛이 여러 행일 수 있다
- 그래서 실질적으로는
상반기 1개 주문량 + 7월 같은 맛들의 합계
를 구하는 구조가 더 명확하다
순서
FROM → JOIN ON → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
HAVING 설명
핵심은 GROUP BY가 무슨 기준으로 묶을지를 정하는 것이고,
HAVING은 그렇게 묶인 결과에 조건을 거는 것이기 때문이다.
예를 들어:
SELECT F.FLAVOR
FROM FIRST_HALF AS F
JOIN JULY AS J
ON F.FLAVOR = J.FLAVOR
GROUP BY F.FLAVOR
HAVING SUM(J.TOTAL_ORDER) > 1000;
이 뜻은:
- F.FLAVOR 기준으로 행들을 묶는다
- 각 맛 그룹마다 J.TOTAL_ORDER를 합친다
- 그 합이 1000보다 큰 그룹만 남긴다
즉,
- GROUP BY F.FLAVOR → 묶는 기준
- HAVING SUM(J.TOTAL_ORDER) > 1000 → 묶인 그룹에 대한 조건
이라서 전혀 이상하지 않다.
비유하면:
- GROUP BY F.FLAVOR = 맛별로 반을 나눈다
- HAVING SUM(J.TOTAL_ORDER) > 1000 = 각 반의 7월 주문량 총합이 1000 넘는 반만 남긴다
왜 J를 써도 되냐면,
JOIN이 끝난 뒤에는 F와 J가 합쳐진 결과 집합 위에서 그룹을 만들기 때문이다.
예를 들어 join 결과가 이렇게 생겼다고 하자.
| F.FLAVOR | F.TOTAL_ORDER | J.TOTAL_ORDER |
| mango | 2900 | 790 |
| mango | 2900 | 110 |
| peach | 2450 | 500 |
여기서 GROUP BY F.FLAVOR를 하면:
- mango 그룹
- peach 그룹
이렇게 묶인다.
그 다음 HAVING SUM(J.TOTAL_ORDER) > 800 을 하면:
- mango → 790 + 110 = 900 → 통과
- peach → 500 → 탈락
이런 식이다.
중요한 점 하나 더 있다.
HAVING 안에는 보통 이런 것들이 온다.
- 집계함수
SUM(J.TOTAL_ORDER)
COUNT(*)
AVG(...) - 또는 GROUP BY에 쓴 컬럼
F.FLAVOR
즉 이런 건 자연스럽다.
HAVING SUM(J.TOTAL_ORDER) > 1000
HAVING F.FLAVOR = 'mango'
반면 이런 건 조심해야 한다.
HAVING J.TOTAL_ORDER > 1000
이건 J.TOTAL_ORDER가 그룹 안에 여러 개 있을 수 있어서
집계하지 않으면 애매해질 수 있다.
한 줄로 정리하면 이렇다.
GROUP BY는 묶는 기준이고, HAVING은 그 그룹 안의 값들을 집계해서 조건을 거는 것이다. 그래서 그룹 기준이 F여도 HAVING에서 J의 집계값을 써도 된다.
'프로그래머스 > 코딩테스트' 카테고리의 다른 글
| SQL LV4) 년, 월, 성별 별 상품 구매 회원 수 구하기[다시] (0) | 2026.04.15 |
|---|---|
| SQL LV2) 조건에 맞는 아이템들의 가격의 총합 구하기 (0) | 2026.04.15 |
| sql lv 2)조건에 맞는 도서와 저자 리스트 출력하기 (0) | 2026.04.13 |
| lv1 체육복 [다시] (0) | 2026.04.06 |
| lv 2 ) 큰 수 만들기 (0) | 2026.04.04 |
