2.4 Having (SQL)
HAVING 개요
Table 0: Film Table
film_id | title | rental_rate | length |
---|---|---|---|
1 | 명량 | 4.99 | 120 |
2 | 암살 | 2.99 | 90 |
3 | 어벤져스 | 0.99 | 80 |
4 | 기생충 | 2.99 | 60 |
5 | 어바웃 타임 | 2.99 | 100 |
HAVING은 집계 함수를 사용하여 데이터를 필터링하는 기능이다. Film 테이블에서 대여료(rental_rate)별로 집계했을 때 평균 상영 시간이 100분 미만인 대여료를 조회해보자. 일반적으로 조건 검색에는 WHERE 구문을 사용하지만, WHERE 구문에서는 집계 함수를 사용할 수 없다:
1
2
3
4
SELECT rental_rate FROM film WHERE AVG(length) < 100 GROUP BY rental_rate;
-- 조회 결과:
-- ERROR: Aggregate functions are not allowed in WHERE
위의 예시처럼 WHERE절 안에 집계 함수를 사용하게되면, 사용할 수 없다는 문구와 함께 오류를 반환한다. 이렇게 집계함수를 이용하여 조건을 걸고싶은 경우 WHERE 대신 HAVING을 사용하여 조회할 수 있다:
1
2
3
4
5
6
7
8
9
SELECT rental_rate FROM film GROUP BY rental_rate HAVING AVG(length) < 100;
-- 조회 결과:
-- +-----------+
-- |rental_rate|
-- +-----------+
-- | 0.99 |
-- | 2.99 |
-- +-----------+
WHERE와의 조합
WHERE와 HAVING을 조합하여 사용하면 복잡한 조건의 쿼리문을 작성할 수 있다. 예를 들어 대여료 (rental_rate)가 2.99가 아니고 대여료별로 집계했을 때 평균 상영시간이 100 미만인 대여료를 조회해보자:
1
2
3
4
5
6
7
8
SELECT rental_rate FROM film WHERE rental_rate != 2.99 GROUP BY rental_rate HAVING AVG(length) < 100;
-- 조회 결과:
-- +-----------+
-- |rental_rate|
-- +-----------+
-- | 0.99 |
-- +-----------+
GROUP BY를 기준으로 WHERE는 GROUP BY의 앞에, HAVING은 뒤에 위치한다. 이 쿼리는 다음과 같은 단계로 나누어 동작한다.
- FROM, WHERE, SELECT 절에 의한 데이터 조회
- GROUP BY로 지정된 컬럼으로 그룹화
- 집계 함수의 계산
- HAVING 절에 의한 필터링
- 결과의 반환
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
+--------+---------+-----------+--------+
|film_id | title |rental_rate| length |
+--------+---------+-----------+--------+
| 1 | 명량 | 4.99 | 120 |
| 2 | 암살 | 2.99 | 90 |
| 3 | 어벤져스 | 0.99 | 80 |
| 4 | 기생충 | 2.99 | 60 |
| 5 |어바웃 타임 | 2.99 | 100 |
+--------+---------+-----------+--------+
|
| (1)
V
+--------+---------+-----------+--------+
|film_id | title |rental_rate| length |
+--------+---------+-----------+--------+
| 1 | 명량 | 4.99 | 120 |
| 3 | 어벤져스 | 0.99 | 80 |
+--------+---------+-----------+--------+
|
| (2), (3)
V
+-----------+--------+
|rental_rate| avg |
+-----------+--------+
| 0.99 | 80 |
| 4.99 | 120 |
+-----------+--------+
|
| (4), (5)
V
+-----------+--------+
|rental_rate| avg |
+-----------+--------+
| 0.99 | 80 |
+-----------+--------+
This post is licensed under CC BY 4.0 by the author.