'HAVING 절'에 해당되는 글 1건

728x90

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 절을 사용한다고 기억하면 된다.


블로그 이미지

Link2Me

,