포스트

03. GROUP_BY_HAVING

GROUP_BY_HAVING

1
2
3
4
5
6
7
8
9
10
11
12
< SELECT문 해석 순서 >
5) SELECT 컬럼명 AS 별칭, 계산식, 함수식
1) FROM 참조할 테이블명
2) WHERE 컬럼명 | 함수식 비교연산자 비교값
3) GROUP BY 그룹을 묶을 컬럼명
4) HAVING 그룹함수식 비교연산자 비교값
6) ORDER BY 컬럼명 | 별칭 | 컬럼순번 정렬방식[NULL FIRST / LAST]

해석순서 : FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

해석순서에 의해 ORDER BY에는 별칭, 컬럼순서로 컬럼명을 대체 가능하지만 
HAVING에서는 불가능하다

1) GROUP BY절

1
2
3
4
5
6
< GROUP BY절 >
✔ 같은 값들이 여러개 기록된 컬럼을 가지고 같은 값들을 하나의 그룹으로 묶음

GROUP BY 컬럼명 | 함수식
✔ 여러개의 값을 묶어서 하나로 처리할 목적으로 사용함
✔ 그룹으로 묶은 값에 대해서 SELECT절에서 그룹함수를 사용함
1
2
3
4
5
6
7
8
SELECT DEPT_CODE FROM EMPLOYEE; -- 23행

SELECT SAU(SALARY) FROM EMPLOYEE; -- 1행 

SELECT DEPT_CODE , SUM(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE;
-- DEPT_CODE가 같은 행끼리 하나의 그룹이 됨
1
2
3
4
5
6
7
8
9
10
-- < 연습문제 !! >
-- EMPLOYEE 테이블에서
-- 성별(남/여)과 각 성별 별 인원 수, 급여 합을
-- 인원 수 오름 차순으로 조회

SELECT DECODE(SUBSTR(EMP_NO, 8, 1), '1', '남', '2', '여') "성별",
	COUNT(*) "인원 수" , SUM(SALARY) "급여 합"
FROM EMPLOYEE
GROUP BY SUBSTR(EMP_NO, 8, 1) -- 별칭사용x (SELECT 해석 전)
ORDER BY "인원 수"; -- 별칭사용o (SELECT 해석 후)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- < 연습문제 !! >
-- EMPLOYEE 테이블에서 
-- 직급별 2000년도 이후(2000년 포함) 입사자들의 급여 합을 조회
-- 직급코드 오름차순

SELECT JOB_CODE "직급코드" , SUM(SALARY) "급여 합"
FROM EMPLOYEE
GRROUP BY JOB_CODE
WHERE EXTRACT(YEAR FROM HIRE_DATE) >= 2000 
-- 형변환이 없기 때문에 연산이 가장 빠르다
-- HIRE_DATE >= TO_DATE('2000-01-01') 
-- (= HIRE_DATE >= '2000-01-01') 자동형변환 -- 형변환 1번
-- TO_NUMBER(SUBSTR(TO_CHAR(HIRE_DATE), 1, 4)) >= 2000 -- 형변환이 많다
GROUP BY JOB_CODE
ORDER BY 1;
1
2
3
4
5
6
7
8
9
-- < 연습문제 !! >
-- EMPLOYEE 테이블에서 부서별로 같은 직급인 사원의 수를 조회
-- 부서코드는 오름차순, 직급코드는 내림차순

SELECT DEPT_CODE , JOB_CODE , COUNT(*)
FROM EMPLOYEE
GROUP BY DEPT_CODE, JOB_CODE 
-- DEPT_CODE로 그룹을 나누고, 나눠진 그룹 내에서 JOB_CODE로 또 그룹을 분류
ORDER BY DEPT_CODE, JOB_CODE DESC;
1
2
3
4
5
6
-- < 💡 TIP !! >

-- ✔ GROUP BY 사용시 주의사항
--> SELECT문에 GROUP BY절을 사용할 경우
-- SELECT절에 명시한 조회하려는 컬럼 중
-- 그룹함수가 적용되지 않은 컬럼을 모두 GROUP BY절에 작성!!

2) HAVING

  • GROUP 전체의 조건을 적용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-- 부서별 평균 급여가 3백만원 이상인 부서를 조회(부서코드 오름차순)

SELECT DEPT_CODE , AVG(SALARY)
FROM EMPLOYEE
WHERE SALARY >= 3000000
GROUP BY DEPT_CODE
ORDER BY 1;
-- 한 사람의 급여가 300만 이상이라는 조건

SELECT DEPT_CODE , AVG(SALARY)
FROM EMPLOYEE
GROUP BY DEPT_CODE
HAVING AVG(SALARY) >= 3000000
ORDER BY 1;
-- DEPT_CODE로 묶은 그룹 중 급여 평균이 300만 이상인 그룹만 걸러냄
1
2
3
4
5
6
7
8
9
-- EMPLOYEE 테이블에서 
-- 직급별 인원수가 5명 이하인 직급코드, 인원 수 조회(직급코드 오름차순)

SELECT JOB_CODE, COUNT(*)
FROM EMPLOYEE
GROUP BY JOB_CODE
HAVING COUNT(*) <= 5
ORDER BY 1;
-- HAVING절에는 그룹 함수가 반드시 작성된다
1
2
3
4
5
HAVING 에는
(1) 그룹함수 사용 가능
(2) 그룹함수 간의 비교 가능
(3) GROUP BY에 쓰인 컬럼 가능
(4) AND, OR 사용 가능