(SQL) 데이터 그룹핑 (GROUP BY, HAVING)
(SQL) 데이터 그룹핑하기
우리는 그룹핑을 통해 데이터를 요약할 수 있다.
SQL은 GROUP BY절을 통해 데이터 그룹핑을 지원한다.
HAVING 절을 이용하여 그룹핑에 조건도 추가할 수 있다.
데이터 파악에 큰 도움을 주는 데이터 그룹핑에 대해 살펴보자.
1) 그룹핑하기 : GROUP BY
2) GROUP BY절의 주요 규칙
3) 그룹 필터링 : HAVING
4) HAVING vs WHERE
1. 그룹핑하기 : GROUP BY
그룹핑은 다음과 같은 상황에서 주로 쓰인다.
- 레코드가 종류별로 몇개가 있는지 세고 싶을 때.
- 레코드의 총합을 종류별로 알고 싶을 때.
- 레코드를 종류별로 집계하고, 조건에 따라 필터링하고 싶을 때.
SELECT 문에서 GROUP BY 절을 사용하여 그룹을 생성할 수 있다.
SELECT
vend_id
, COUNT(*) AS num_prods
FROM Products
GROUP BY vend_id
;
위의 구문은 GROUP BY 절을 사용한 예시이다.
vend_id별로 그룹핑하고, 그룹별로 레코드의 개수를 출력했다.
(그룹 계산 함수로 COUNT 함수 사용)
2. GROUP BY 절의 주요 규칙
GROUP BY절의 주요 규칙은 다음과 같다.
GROUP BY 절은 원하는 만큼의 열을 써서, 중첩 그룹을 만들 수 있다.
GROUP BY 절은 WHERE 절 뒤에, 그리고 ORDER BY 절 앞에 와야 한다.
- ORDER BY절은 항상 구문 마지막에 사용하자
- GROUP BY절은 데이터 정렬이 안될 때도 많다.
따라서 정렬을 원한다면 ORDER BY를 이용하자.
- ORDER BY절은 항상 구문 마지막에 사용하자
3. 그룹 필터링 : HAVING
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;
4. HAVING vs WHERE
앞서 살펴본 것처럼, >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