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;
 

이 뜻은:

  1. F.FLAVOR 기준으로 행들을 묶는다
  2. 각 맛 그룹마다 J.TOTAL_ORDER를 합친다
  3. 그 합이 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의 집계값을 써도 된다.

 

+ Recent posts