(SQL) 데이터 그룹핑 (GROUP BY, HAVING)
(SQL) 데이터 그룹핑하기
우리는 그룹핑을 통해 데이터를 요약할 수 있다.
SQL은 GROUP BY절을 통해 데이터 그룹핑을 지원한다.
HAVING 절을 이용하여 그룹핑에 조건도 추가할 수 있다.
데이터 파악에 큰 도움을 주는 데이터 그룹핑에 대해 살펴보자.
1) 그룹핑하기 : GROUP BY
2) GROUP BY절의 주요 규칙
3) 그룹 필터링 : HAVING
4) HAVING vs WHERE
그룹핑은 다음과 같은 상황에서 주로 쓰인다.
- 레코드가 종류별로 몇개가 있는지 세고 싶을 때.
- 레코드의 총합을 종류별로 알고 싶을 때.
- 레코드를 종류별로 집계하고, 조건에 따라 필터링하고 싶을 때.
SELECT 문에서 GROUP BY 절을 사용하여 그룹을 생성할 수 있다.
SELECT
vend_id
, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id
;
위의 구문은 GROUP BY 절을 사용한 예시이다.
vend_id별로 그룹핑하고, 그룹별로 레코드의 개수를 출력했다.
(그룹 계산 함수로 COUNT 함수 사용)
GROUP BY절의 주요 규칙은 다음과 같다.
GROUP BY 절은 원하는 만큼의 열을 써서, 중첩 그룹을 만들 수 있다.
GROUP BY 절은 WHERE 절 뒤에, 그리고 ORDER BY 절 앞에 와야 한다.
- ORDER BY절은 항상 구문 마지막에 사용하자
- GROUP BY절은 데이터 정렬이 안될 때도 많다.
따라서 정렬을 원한다면 ORDER BY를 이용하자.
- ORDER BY절은 항상 구문 마지막에 사용하자
SQL은 데이터를 그룹핑하는 것 뿐만 아니라,
그룹 필터링도 가능하게 해준다.
대표적인 예로 다음과 같은 상황이 있다.
- 최소 3번 이상 주문한 고객 리스트.
- 총 주문금액이 30000원 이상인 고객 리스트
그룹 필터링은 HAVING 절을 이용한다.
HAVING절의 문법은 WHERE절의 문법과 동일하다.
따라서, HAVING 절은 연산자나 연산키워드를 포함하여 사용하면 된다.
| 연산자 | 설명 |
|---|---|
| = | 같다 |
| <> | 같지 않다. |
| != | 같지 않다. |
| < | ~ 보다 작다 |
| <= | ~ 이하 이다. |
| !< | ~ 보다 작지 않다. |
| > | ~ 보다 크다 |
| >= | ~이상 이다. |
| !> | ~ 보다 크지 않다. |
| BETWEEN | 두 개의 특정한 값 사이 |
| IS NULL | 값이 NULL 이다. |
GROUP BY와 HAVING 절을 이용하여
최소 3번 이상 주문한 고객 리스트를 뽑아보는 구문은 아래와 같다.
SELECT cust_id, COUNT(*) AS orders
FROM Orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
앞서 살펴본 것처럼, >HAVING절과 WHERE절은 데이터를 필터링할 때 사용한다.
그렇다면, 이 둘의 차이는 무엇일까?
두 절의 차이는 WHERE절은 데이터가 그룹핑되기 전에 필터링하고,
HAVING 절은 데이터가 그룹핑된 후에 필터링한다는 점이다.
WHERE 절에서 필터링되어 제거된 행은 그룹에 포함되지 않는다.
WHERE절과 HAVING절을 동시에 사용하여 더 세부적인 필터링을 할 수 있다.
예를 들어, 지난 1년동안 두 번 이상 주문한 적이 있는 고객만을 뽑아내고 싶다고 하자.
이 경우, WHERE절로 지난 1년 동안 주문했던 고객을 필터링하고,
그 다음 , HAVING 절을 이용하여 결과에서 두 번 이상 주문한 고객을 필터링하면 된다.
구문은 다음과 같다.
SELECT
vend_id
, COUNT(*) AS num_prods
FROM Products
WHERE 1=1
AND prod_price >= 4
GROUP BY vend_id
HAVING COUNT(*) >= 2;
대다수 DBMS에서 GROUP BY가 명시되지 않는다면,
HAVING절과 WHERE 절은 똑같이 처리한다.
하지만 디버깅과 업무효율화를 위해,
이 둘을 꼭 구별하여 사용하자.
- GROUP BY 집계 전 필터링 : WHERE
- GROUP BY 집계 후 필터링 : HAVING