공든탑앱 열기

집계 함수와 GROUP BY·HAVING

SQLD (SQL 개발자) · SQL 기본 · 약 14분

쉽게 말하면

집계 함수는 여러 줄을 모아 합계, 평균, 개수 같은 숫자 하나로 만들어요. GROUP BY를 쓰면 부서별, 지역별처럼 무리를 나눠서 무리마다 따로 계산해요. HAVING은 그렇게 만든 무리 중에서 조건에 맞는 무리만 남겨요. 줄을 먼저 거르는 건 WHERE, 무리를 거르는 건 HAVING이에요.

시험용 정의

집계 함수(COUNT, SUM, AVG, MAX, MIN)는 여러 행을 모아 값 하나를 만든다. GROUP BY는 행을 같은 값끼리 묶어 그룹마다 집계하게 하고, HAVING은 그 그룹에 조건을 건다. 행에 조건을 거는 WHERE는 그룹을 만들기 전, HAVING은 그룹을 만든 후에 동작한다. 집계 함수는 NULL을 빼고 계산한다(COUNT(*)만 예외).

비유로 이해하기

반 대항 체육대회 점수 집계다. 학생 성적표(행)를 반별로 모으고(GROUP BY), 반마다 합계를 내고(SUM), 합계가 300점 넘는 반만 결승에 올린다(HAVING). 결석생을 미리 빼는 건 WHERE다.

자세히

먼저 알아 둘 말

말뜻
집계 함수여러 행을 받아 결과 하나를 내는 함수. 다중행 함수, 그룹 함수라고도 한다
그룹GROUP BY에 쓴 열 값이 같은 행들의 묶음
ORA-00979GROUP BY 표현식이 아닙니다. GROUP BY에 없는 열을 집계 없이 SELECT에 쓰면 난다
ORA-00934그룹 함수는 허가되지 않습니다. WHERE에 집계 함수를 쓰면 난다

집계 함수

함수뜻NULL
COUNT(*)행 수NULL 상관없이 모든 행
COUNT(열)그 열이 NULL이 아닌 행 수NULL 제외
COUNT(DISTINCT 열)서로 다른 값의 개수NULL 제외
SUM / AVG합계 / 평균NULL 제외 (AVG는 NULL 아닌 개수로 나눔)
MAX / MIN최댓값 / 최솟값 (문자·날짜도 됨)NULL 제외

WHERE vs HAVING

구분WHEREHAVING
거르는 대상행 하나하나GROUP BY로 만든 그룹
처리 시점그룹을 만들기 전그룹을 만든 후
집계 함수쓸 수 없다쓸 수 있다 (COUNT(*) >= 3)
예WHERE deptno IS NOT NULLHAVING SUM(sal) > 15000

알아 둘 규칙

  • GROUP BY를 쓰면 SELECT에는 GROUP BY 열과 집계 함수만 쓴다
  • GROUP BY 없이 집계 함수와 일반 열을 함께 쓰면 오류(ORA-00937)
  • GROUP BY 절에는 SELECT의 별칭을 쓸 수 없다 (GROUP BY가 SELECT보다 먼저 처리되기 때문)
  • GROUP BY 없이 HAVING만 쓰면 테이블 전체가 한 그룹이 된다
  • 행이 0개여도 GROUP BY 없는 집계는 결과 1행을 돌려준다 (COUNT는 0, SUM은 NULL)

시험에 이렇게 나와요

출제 범위·공식 안내 기반

확인 문제

Q1. SELECT deptno, ename, SUM(sal) FROM emp GROUP BY deptno을 실행하면?

  1. 오류가 난다
  2. 부서별 합계만 나오고 이름은 첫 사원
  3. 이름별로 합계가 나온다
  4. 부서별 합계와 이름이 모두 나온다
정답 보기

1번 오류가 난다

GROUP BY를 쓰면 SELECT에는 GROUP BY에 쓴 열이나 집계 함수만 올 수 있다. 부서 하나에 이름이 여러 개라 무엇을 보여 줄지 정할 수 없으므로 오류(ORA-00979)다.

Q2. COMM이 (NULL, 300, 0, NULL, 500)인 5행에서 COUNT(*), COUNT(comm), SUM(comm)은?

  1. 3, 3, 800
  2. 5, 2, 800
  3. 5, 5, 800
  4. 5, 3, 800
정답 보기

4번 5, 3, 800

COUNT(*) = 5, COUNT(comm)은 NULL 아닌 300·0·500 → 3, SUM = 800.

Q3. 부서별 평균 급여가 3000 이상인 부서를 찾는 올바른 SQL은?

  1. SELECT deptno FROM emp GROUP BY deptno HAVING AVG(sal) >= 3000
  2. SELECT deptno, AVG(sal) FROM emp GROUP BY AVG(sal) >= 3000
  3. SELECT deptno FROM emp HAVING sal >= 3000
  4. SELECT deptno FROM emp WHERE AVG(sal) >= 3000 GROUP BY deptno
정답 보기

1번 SELECT deptno FROM emp GROUP BY deptno HAVING AVG(sal) >= 3000

그룹 조건은 HAVING. WHERE에는 집계 함수를 쓸 수 없다.

Q4. SELECT COUNT(*), SUM(sal) FROM emp WHERE 1 = 2의 결과는?

  1. 0, 0 (1행)
  2. 결과 없음(0행)
  3. 오류
  4. 0, NULL (1행)
정답 보기

4번 0, NULL (1행)

GROUP BY 없는 집계는 행이 없어도 1행을 돌려준다. COUNT는 0, SUM은 NULL.

Q5. SELECT deptno, ename, SUM(sal) FROM emp GROUP BY deptno 의 결과는?

  1. ename이 GROUP BY에 없어 오류
  2. 부서마다 첫 사원 이름
  3. 이름별 합계
  4. 부서별 합계와 사원 이름
정답 보기

1번 ename이 GROUP BY에 없어 오류

GROUP BY에 없는 열을 집계 없이 SELECT에 쓰면 오류다.

Q6. SAL이 (100, NULL, 300)인 3행에서 AVG(sal)의 결과는?

  1. 200
  2. 400
  3. 약 133.3
  4. NULL
정답 보기

1번 200

NULL을 뺀 2행으로 나눈다. (100 + 300) / 2 = 200.

헷갈리기 쉬운 O·X

HAVING 절은 GROUP BY 절 없이 쓸 수 없다.

정답 보기

X GROUP BY 없이 쓰면 전체가 한 그룹으로 취급된다.

GROUP BY 절에는 SELECT 절에서 정의한 별칭을 쓸 수 없다.

정답 보기

O GROUP BY가 SELECT보다 먼저 처리된다.

MAX, MIN 함수는 숫자 열에만 쓸 수 있다.

정답 보기

X 문자·날짜에도 쓸 수 있다.

함께 보면 좋은 개념