[그룹 함수와 Having 절]
; 그룹 함수를 포함한 조건은 일반 조건과 계산하는 시점이 다르다.
일반 조건의 경우 컬럼의 값을 단지 조건과 비교하면 되지만
그룹 함수의 결과를 조건으로 하는 경우 GROUP BY 절의 사용 유무에 따라 결과 값이 달라지므로
조건에 그룹 함수가 포함된 경우 이것은 일반 조건과 동일한 시점에 처리할 수 없다.
SQL 은 이를 위해 HAVING 절을 제공한다.
HAVING 절은 조건 중에 그룹 함수가 포함된 것만을 모아서
기술하는 구문이다.
SELECT 컬럼 or 그룹함수...
FROM 테이블
WHERE 일반 조건
GROUP BY 그룹대상 (일반 컬럼)
HAVING 그룹함수포함조건
ORDER BY 정렬 대상;
1) HAVING : 조건 중에 그룹함수를 포함하는 조건 기술
2) HAVING 절은 GROUP BY 절 뒤에 기술한다
3) HAVING 절의 해석은 WHERE 절과 동일하다
다만 그룹 함수를 포함하는 조건은
HAVING 절에 해야만 한다
-------------------------------------------------------------------------
SELECT eno, ename --3
FROM emp --1
WHERE dno='20'; --2 (순서)
1) 부서별로 평균 급여가 3000 이상인 부서만 출력하세요
--그룹함수가 포함되는 시점부터 -> 그룹함수가 계산이 먼저 되고 그다음 조건비교가 일어나야함. 그래서 WHERE절이 있으면 X.
SELECT dno, ROUND(AVG(sal)) --2
FROM emp --1
GROUP BY dno; --3
--그룹함수 조건은 WHERE절에 사용할 수 없다!!!!!! -- 호출 시점이 다르기 떄문에.
SELECT dno, ROUND(AVG(sal))
FROM emp
WHERE (sal) >= 3000 -- 불가. dno는 가능함.
GROUP BY dno;
SELECT dno, ROUND(AVG(sal)) --3
FROM emp --1
GROUP BY dno --2
HAVING AVG(sal) >= 3000; --4
--where 절과 같음. 그룹함수의 조건을 쓰라고 만들어 놓은것
2) 20번 부서가 아니면서 평균 급여가 3000 이상인 부서만 출력
SELECT dno, ROUND (AVG(sal))
FROM emp
WHERE dno != 20 -- 일반조건 순서는 여기에 있어야 함...
GROUP BY dno -- 그룹
HAVING ROUND(AVG(sal)) >=3000; -- 그룹 조건
1)GROUP BY 절에 따른 그룹 함수 결과 값의 변화
2) 부서별 급여 평균이 3천 달러 미만인 부서의 부서번호와
평균 급여를 검색한다
SELECT dno, ROUND(AVG(sal))
FROM emp
GROUP BY dno
HAVING AVG(sal)<3000;
3) 개발 업무가 아닌 부서별 인원수를 검색하세요
SELECT dno, job, COUNT(*) 인원수
FROM emp
WHERE job !='개발'
GROUP BY dno, job; -- 01 경영/ 01 지원 -> 01 번 부서로 똑같지만 job이 달라서 두개로 나뉨
4) 그룹함수의 조건인 아닌 것은 WHERE 절에 기술한다
5) HAVING 절은 그룹함수의 조건이나
GROUP BY 에 기술한 컬럼의 조건이 가능하다
그러나 HAVING 절은 그룹함수의 조건만 사용하고
GROUP BY 에 있는 컬럼이라도 WHERE 절에 사용하는 것을
권장한다.
연습문제
1) 화학과를 제외하고 학생들의 평점 평균을 검색하세요
--SELECT major, ROUND(AVG(avr), 2)
SELECT major, TO_CHAR((AVG(avr), '9.99'))
FROM student
WHERE major != '화학'
GROUP BY major;
2) 화학과를 제외한 각 학과별 평균 평점 중에 평점이 2.0 이상인 정보를 검색하세요
SELECT major, TO_CHAR(AVG(avr), '9.99')
FROM student
WHERE major != '화학'
HAVING AVG(avr) > 2.0
GROUP BY major;
3) 기말고사 평균이 60점 이상인 학생의 정보를 검색하세요(학번과 기말고사 평균)
SELECT sno, ROUND(AVG(result), 2)
FROM score
--HAVING AVG(result) >='60'
HAVING AVG(result) >= 60 --이 더 나음
GROUP BY sno;
4) 강의 학점수가 3학점 이상인 교수의 정보를 검색하세요(교수번호, 이름과 담당 학점수)
SELECT pno, pname, SUM(st_num)
FROM professor
NATURAL JOIN course
HAVING SUM(st_num)>=3
GROUP BY pno, pname;
'DB > Oracle SQL Developer' 카테고리의 다른 글
<35, 36> 다중 행, 열 (0) | 2020.12.02 |
---|---|
<33, 34> 단일행 서브쿼리 (0) | 2020.12.02 |
<29, 30> GROUP (0) | 2020.12.02 |
<27, 28> 단일행 함수 - 변환함수 (0) | 2020.12.02 |
<25, 26> 단일행 함수 - 숫자, 날짜형 함수 (0) | 2020.12.02 |
댓글