728x90
GROUP BY, HAVING, ORDER BY의 진짜 실행 흐름 알아보기
SQL을 처음 배울 때 우리는 다음과 같이 쿼리를 작성합니다:
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(USER_ID) >= 2
ORDER BY USER_ID, PRODUCT_ID DESC;
겉으로 보기엔 그냥 "온라인 판매 내역에서 사용자와 상품별로 묶고, 두 번 이상 구매한 조합만 출력해서 정렬"하는 것처럼 보이죠.
하지만... 이 쿼리, 우리가 작성한 순서 그대로 실행되지 않습니다.
오늘은 이 쿼리를 예로 들어 SQL의 진짜 실행 순서와 그 흐름을 이해해봅시다!
🧠 SQL의 논리적 실행 순서
SQL은 아래 순서로 내부적으로 실행됩니다:
- FROM: 테이블 또는 뷰에서 데이터를 가져옴
- WHERE: 조건에 맞는 행만 필터링
- GROUP BY: 행들을 그룹으로 묶음
- HAVING: 그룹 단위의 조건 필터링
- SELECT: 컬럼을 선택
- ORDER BY: 결과 정렬
- LIMIT: 출력 개수 제한 (옵션)
예제 테이블
ONLINE_SALE이라는 테이블이 있다고 가정해봅시다:
USER_IDPRODUCT_ID
| 1 | A |
| 1 | A |
| 1 | B |
| 2 | A |
| 2 | A |
| 3 | C |
이 쿼리는 실제로 이렇게 동작합니다
SELECT USER_ID, PRODUCT_ID
FROM ONLINE_SALE
GROUP BY USER_ID, PRODUCT_ID
HAVING COUNT(USER_ID) >= 2
ORDER BY USER_ID, PRODUCT_ID DESC;
① FROM
먼저 테이블 전체 데이터를 읽습니다.
(6 rows loaded from ONLINE_SALE)
② GROUP BY
USER_ID, PRODUCT_ID 조합이 같은 행끼리 묶습니다. 즉, 다음과 같은 그룹들이 생깁니다:
- (1, A) → 2건
- (1, B) → 1건
- (2, A) → 2건
- (3, C) → 1건
이렇게 그룹핑된 데이터는 마치 가상의 테이블처럼 존재하게 됩니다.
③ HAVING
각 그룹에 대해 조건을 검사합니다. 여기서는 COUNT(USER_ID) >= 2 조건이므로:
- (1, A) → ✅ (2건)
- (2, A) → ✅ (2건)
- (1, B), (3, C) → ❌ (1건)
조건에 맞는 그룹만 남습니다.
④ SELECT
이제 USER_ID, PRODUCT_ID 컬럼만 뽑아냅니다:
USER_ID | PRODUCT_ID
--------+------------
1 | A
2 | A
⑤ ORDER BY
USER_ID 오름차순, PRODUCT_ID 내림차순으로 정렬됩니다:
USER_ID | PRODUCT_ID
--------+------------
1 | A
2 | A
💡 WHERE vs HAVING 차이점은?
많은 분들이 헷갈리는 부분!
- WHERE → 그룹핑 전에 사용. 개별 행 기준으로 필터링함.
- HAVING → 그룹핑 후에 사용. 그룹에 대해 조건을 거는 것.
✅ 마무리 요약
- SQL은 작성한 순서가 아니라 논리적 실행 순서에 따라 동작합니다.
- GROUP BY는 "가상의 그룹 테이블"을 만들어내며, 여기에 HAVING을 적용합니다.
- ORDER BY는 마지막에 정렬만 할 뿐, 그룹핑이나 필터링에는 영향을 주지 않아요.
✍️ 마지막으로
SQL 쿼리를 쓸 때 항상 이 실행 순서를 떠올리면:
- 더 직관적인 쿼리를 쓸 수 있고,
- 성능이나 정확성 이슈도 줄일 수 있어요.
특히 GROUP BY와 HAVING을 사용할 때는 "지금 내가 묶은 건 뭐고, 어떤 그룹을 거르려는가?"를 명확히 인식하는 것이 중요합니다.
SQL을 더 잘 쓰고 싶다면? 순서를 기억하세요. FROM → GROUP BY → HAVING → SELECT → ORDER BY!
'SQL' 카테고리의 다른 글
| POSTGRES 알아보기 3 (0) | 2024.03.07 |
|---|---|
| POSTGRESQL 알아보기2 (0) | 2024.03.07 |
| POSTGRESQL 알아보기 (1) | 2024.03.07 |
| [프로그래머스SQL] 없어진 기록 찾기 (0) | 2024.02.11 |
| 리눅스 환경에서 MySQL 세팅하기 (0) | 2024.01.25 |