본문 바로가기

SQL

SQL [9] - GROUP BY와 HAVING (+ ROLL UP, GROUPING SET)

1. Group by : 컬럼을 기준으로 레코드를 그룹화 하기 위한 조건 

복수행(그룹) 함수 : 여러행에 대한 정보를 조회하는 함수 

 

예를 들면 학생 테이블에는 학년(grade)이 1,2,3,4학년으로 총 4가지가 있고 총 20명의 학생이 있습니다.

student 테이블의 총 행의 수를 구하고 싶으면 count함수를 이용하면되고, 평균 몸무게를 구하고 싶으면 avg(weight)를 이용하면 됩니다.

 

select count(*) from student ;

select avg(weight) from student ;

count나 avg와 같은 복수행 그룹 함수는 요약 값을 보여주는 함수이기 때문에,

일반적으로 select * from student; 처럼 여러 줄의 리스트 행을 출력하는 구문과 동시에 쓰일 수 없습니다. 

 

select *, count(*) from student ; <-- 오류 발생  

select * from student; 는 행이 20개가 출력되고

select count(*) from student; 는 행이 1개가 출력되기 때문입니다.

 

이처럼 여러 값을 요약해주는 복수행 그룹 함수는 Group by와 함께 쓰일 수 있는데, 아래의 상황을 확인해봅니다.

총 20명의 학생이 데이터를 가지고 있고 각각의 1,2,3,4 학년으로 구분되어 있느 데이터 값에서 

각각의 학년 별 몸무게 평균을 내고 싶으면, group by를 아래와 같이 이용해주면 됩니다.

 

select grade,avg(weight)

from student

group by grade; 

** 복수행 그룹 함수들 
COUNT : 레코드의 건수 / null 값을 제외한 건수
SUM : 합계
AVG 평균
MAX 최댓값
MIN 최소값
STDDEV 표준 편차
VARIANCE 분산

2. Having : 그룹함수의 조건문

Having : 그룹으로 출력된 값들에 조건을 준다 vs Where : 단일행마다 조건을 준다

 

학년별 몸무게 평균이 60이상인 그룹 값들 출력하기  

select grade,avg(weight)

from student

group by grade

having avg(weight) >= 60; 

 

3. ROLL UP 자동 소계 산출 함수 

-- 그룹에 ROLLUP() 함수를 사용하면 각 그룹마다 하단 행에 소계 값이 나온다.

select deptno, position, count(*), sum(pay) 
from professor
group by deptno, position
order by deptno
;

select deptno, position, count(*), sum(pay) 
from professor
group by rollup(deptno, position)
order by deptno
;

3,7,14,17 행처럼 NULL으로 표현되어 자동합계가 나온다.

해당 값을 '소계'로 바꾸고 싶으면, nvl을 null 값이 출력되는 포지션 열에 사용하면 된다. 

select deptno, nvl(position,'소계'), count(*), sum(pay) 
from professor
group by rollup(deptno, position)
order by deptno
;

 

4. Grouping Set 함수

-- grouping sets 함수 사용하기
-- 각각의 컬럼으로 그룹화하여 결과 리턴 
select grade, deptno1, count(*) from student
group by grouping sets(grade, deptno1)
;

 

grouping set 사용 안할 시,

select grade, deptno1, count(*) from student
group by grade, deptno1
;