VillageSQL is a drop-in replacement for MySQL with extensions.
All examples on this page work on VillageSQL. Install Now →
WHERE는 행이 그룹으로 묶이기 전에 행을 버립니다. HAVING은 그룹이 만들어진 뒤에 그룹 전체를 버립니다. 이 한 문장이 이 수업의 전부이고, 아래의 모든 내용은 그 결과입니다.
시작하기 전에 mysql -u root -p sakila로 클라이언트를 여세요.
HAVING의 동작 방식
GROUPING_COLUMN을 그룹을 정의하는 열로, TABLE_NAME을 테이블로, AGGREGATE_FUNCTION(COLUMN_NAME)을 그룹마다 계산할 것으로, GROUP_CONDITION을 COUNT(*) > 200처럼 그룹 전체에 적용되는 검사로 바꾸세요.
서버는 먼저 모든 그룹을 만든 다음, 조건이 참인 그룹만 남깁니다.
예제
- 큰 그룹만 남기기
- HAVING은 별칭을 사용할 수 있습니다
별칭은 결과의 열에 이름을 붙이고, HAVING이 실행되는 시점에는 그 결과가 존재합니다.
WHERE는 이렇게 할 수 없는데, 이름을 붙일 결과가 생기기 전에 실행되기 때문입니다: WHERE 수업이 대신 받게 되는 ERROR 1054를 보여줍니다.
- 한 쿼리에 두 절을 모두 쓰기
실제 쿼리는 대부분 둘 다 사용합니다: 행을 고르는 데 WHERE를, 그룹을 고르는 데 HAVING을 씁니다.
WHERE가 120분이 넘는 영화를 남겼고, 그룹화가 등급별로 그 수를 세었으며, HAVING이 그 수가 100을 넘는 등급 1개를 남겼습니다.
집계는 WHERE에 들어갈 수 없습니다
그HAVING 조건을 WHERE로 옮기면 서버가 그대로 거부합니다.
WHERE는 그룹화 전에 실행되므로, 검사할 개수가 없습니다. 집계의 별칭에도 같은 규칙이 적용되는데, 오류만 다릅니다.
HAVING으로 옮기세요.
WHERE의 별칭에서 나는 ERROR 1054에는 2가지 해결 방법이 있고, 집계인지 아닌지가 둘을 가릅니다. 일반 표현식의 별칭은 WHERE에서 표현식을 되풀이해 쓸 수 있는데, WHERE 수업이 그것을 보여줍니다. 집계의 별칭은 위의 ERROR 1111 때문에 거기서 전혀 되풀이할 수 없으므로, HAVING으로 옮겨야 합니다.
어느 절이 무엇을 검사하는가
행을 검사하는 조건은 언제나
WHERE에 두고, HAVING은 그룹이 존재해야만 뜻이 통하는 조건에만 쓰세요. 그쪽이 비용도 더 싼 배치인데, 그 이유는 MySQL GROUP BY 성능 가이드가 측정합니다.
HAVING에서 select 목록의 별칭을 참조하는 것은 MySQL 확장입니다. 같은 SQL이 다른 데이터베이스에서도 실행되어야 한다면 별칭 대신 집계를 되풀이해 쓰세요.요약
- 그룹 전체를 버리려면
HAVING을, 행을 버리려면WHERE를 사용하세요. HAVING은GROUP BY뒤에 실행되므로 집계를 검사할 수 있습니다.ERROR 1111은HAVING에 있어야 할 집계가WHERE에 있다는 뜻으로 읽으세요.HAVING에서는 열 별칭을 참조할 수 있고,WHERE는 그렇게 할 수 없습니다.- 그룹이 아니라 행을 검사하는 조건은
WHERE에 두세요.
함께 보기
- GROUP BY — 이 절이 걸러내는 그룹 만들기
- WHERE — 먼저 실행되는 절
- 집계 함수 — 그룹 조건이 보통 검사하는 것
- MySQL GROUP BY 성능 — 걸러내기 전에 그룹화하는 비용