메인 콘텐츠로 건너뛰기

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처럼 그룹 전체에 적용되는 검사로 바꾸세요. 서버는 먼저 모든 그룹을 만든 다음, 조건이 참인 그룹만 남깁니다.

예제

  1. 큰 그룹만 남기기

5개의 등급이 모두 집계되었습니다. 그다음 그룹 3개가 검사에 통과하지 못해 버려졌습니다.

  1. HAVING은 별칭을 사용할 수 있습니다

별칭은 결과의 열에 이름을 붙이고, HAVING이 실행되는 시점에는 그 결과가 존재합니다.
같은 2개의 행이고, 더 짧게 씁니다. WHERE는 이렇게 할 수 없는데, 이름을 붙일 결과가 생기기 전에 실행되기 때문입니다: WHERE 수업이 대신 받게 되는 ERROR 1054를 보여줍니다.

  1. 한 쿼리에 두 절을 모두 쓰기

실제 쿼리는 대부분 둘 다 사용합니다: 행을 고르는 데 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에 두세요.

함께 보기