SQL 그룹함수, having절
단일 행 함수와는 달리 그룹 함수는 여러 행 또는 테이블 전체에 대해 함수가 적용되어 하나의 결과를 가져오는 함수이다.
그룹 당 하나의 결과가 주어지도록 행의 집합에 대해 연산할 경우 GROUP BY절을 이용하여 그룹화 할 수 있고 HAVING를 이용하여 그룹에 대한 조건을 제한할 수 있다
기본구문은 아래와 같다.
SELECT column_name, group_function(column_name)
FROM table_name
WHERE column_name = 'value' -- where 절에는 그룹함수가 올 수 없음
GROUP BY column_name; -- group by 절 뒤에는 컬럼 별칭을 사용할 수 없음
- GROUP BY 절은 데이터들을 원하는 그룹으로 나눌 수 있다.
- 나누고자 하는 그룹의 컬럼명을 SELECT절과 GROUP BY절 뒤에 추가하면 된다.
- 그룹함수를 사용하여 특정 그룹으로 구분할 때는 GROUP BY 절을 사용하며, 특정 그룹없이 중복된 데이터를 제거할 경우에는 DISTINCT 절을 사용한다.
- Count(*) 함수는 서로 다른 모든 행에 대하여 연산하지 않고 각 그룹화된 행에서 계산된다.
그룹함수의 종류
Count : NULL 이 아닌 행의 개수
SUM : NULL 값을 제외한 입력 데이터들의 합계
AVG : NULL 값을 제외한 입력 데이터들의 평균
MAX : 입력 데이터들의 최대 값
MIN : 입력 데이터들의 최소 값
STDDEV : NULL 값을 제외한 입력 데이터들의 표준편차
VARIANCE : NULL 값을 제외한입력 데이터들의 분산 값
예제
-- 각 부서별로 인원수, 급여의 평균, 최저 급여, 최고 급여, 급여의 합을 구하여 급여의 합이 많은 순으로 출력
SQL> SELECT
deptno, count(*), round(avg(sal),0), min(sal), max(sal), sum(sal)
FROM emp
GROUP BY deptno
ORDER BY sum(sal) desc;
-- 업무별로 그룹하여 업무, 인원수, 평균 급여액, 최고 급여액, 최저 급여액 및 합계를 조회
SELECT job, COUNT(empno) "인원수", round(AVG(sal)) "평균급여액", MAX(sal) "최고급여액",
MIN(sal) "최저급여액", SUM(sal) "급여합계"
FROM emp
GROUP BY job;
SELECT deptno, ename, AVG(sal)
FROM emp
GROUP BY deptno;
위 구문은 정상적인 결과를 조회할까?
※ 그룹함수 사용시 GROUP BY 절로 묶이지 않은 단순 컬럼은 SELECT 리스트에 사용 불가능하고 사용시 에러가 발생한다. 정상적으로 처리되려면 SELECT 문에서 ename 을 제거하던가, 아니면 GROUP BY 문에 ename을 추가하던지 해야 한다.
SELECT deptno, ename, AVG(sal)
FROM emp
GROUP BY deptno, ename;
HAVING 절
SELECT COUNT(column) as cnt FROM table GROUP BY column HAVING COUNT(column) > 5;
- WHERE 절에서는 집계함수를 사용 할 수 없다.
- HAVING 절은 집계함수를 가지고 조건비교를 할 때 사용한다.
- HAVING절은 GROUP BY절과 함께 사용된다.
-- 사원수가 다섯 명이 넘는 부서와 사원수를 조회
SELECT d.dname, COUNT(e.empno) "사원수"
FROM emp e, dept d
WHERE e.deptno = d.deptno
GROUP BY d.dname
HAVING COUNT(e.empno) > 5;
ANSI 조인으로 표기하면....
SELECT d.dname, COUNT(e.empno) "사원수"
FROM emp e INNER JOIN dept d
ON e.deptno = d.deptno
GROUP BY d.dname
HAVING COUNT(e.empno) > 5;
-- 전체 월급이 4000을 초과하는 job에 대해서 job과 월급여 합계를 조회.
-- 단 판매원(SALESMAN)은 제외하고 월 급여 합계로 내림차순 정렬
SELECT job, SUM(sal) "급여 합계"
FROM emp
WHERE job != 'SALESMAN' -- 판매원은 제외
GROUP BY job -- 업무별로 Group By
HAVING SUM(sal) > 4000 -- 전체 월급이 4000을 초과하는
ORDER BY SUM(sal) DESC; -- 월급여 합계로 내림차순 정렬
분석 :
먼저 직업별로 조회해본다. select job from emp group by job;
그러면 직업 전체 현황이 조회된다. 판매원을 뜻하는 job 이 뭔지 정확하게 파악할 수 있다.
비교조건이 월급이다.
SUM(sal) > 4000 을 초과하는 job 을 조회하라는 것인데
where 조건에는 그룹함수 SUM(sal) 을 사용하여 비교할 수가 없으므로 Having SUM(sal) 로 비교해야 한다.
**별 평균/합계가 2000 이상 과 같은 조건이 나오면 Group by Having 절을 사용한다고 기억하면 된다.
'SQL' 카테고리의 다른 글
[오라클] SQL 실습을 위한 오라클 11g 설치 (0) | 2014.12.25 |
---|---|
SQL 서브쿼리 (0) | 2014.12.19 |
SQL 숫자함수 및 예제 (0) | 2014.12.17 |
SQL 문자열 처리함수 instr, nvl, lpad 등 (0) | 2014.12.16 |
MySQL 테이블 이름변경, 삭제, 칼럼삭제, 칼럼추가 (0) | 2014.12.08 |