본문 바로가기
개발일지/SQL

*매우중요 oracle developer 기초3. GROUP BY, WHERE, HAVING의 효율적 코드

by 다니엘의 개발 이야기 2022. 9. 9.
320x100

# GROUP BY

예시1
SELECT '영업부', AVG(salary) FROM tstaff
WHERE depart = '영업부';

우선 이것은 그룹핑이 된 쿼리는 아니다.
하지만 단순히 출력의 대상이 1개로 집약되는 이와 같은 쿼리는 또 출력이 가능하다는게 신기하다.



예시2
SELECT depart AS 부서명, ROUND(AVG(salary),2) AS 월급평균
FROM tstaff
GROUP BY depart;

이전에 2개 이상을 SELECT 해서 노출하고 싶었던 기능 그대로다.



예시3
SELECT depart, COUNT(*), MAX(joindate), ROUND(AVG(score),2)
FROM tstaff
GROUP BY depart;

예시3에는 SELECT로 무더기로 4개의 값을 선택하였다.
그럼에도 group by값은 하나인데 출력이 된다.
즉, 기준이 되는 (값이 출력될때 충돌되는 요소가 없게끔) 값을 기준값으로 설정해주는 것이 가장 좋은 것 같다.
GROUP BY 는 '중복값이 있을 때만 의미가 있다'라고 한다



예시4
SELECT gender AS 성별, ROUND(AVG(salary),2) AS 연봉평균
FROM tstaff
GROUP BY gender;



예시5
이건 유의미한 그룹핑은 아니라고 본다.
하지만 한편으로는 유의미하기도 한 그룹핑이다.

SELECT depart, gender, COUNT(*)
FROM tstaff
GROUP BY depart, gender
ORDER BY depart, gender;

중복값이 하나의 범주가 되어야하는 메인이 부서이면서,
해당 부서에 해당하는 남, 여를 분류해서 나오는 결과이기 때문이다.



예시6

SELECT depart, SUM(salary)
FROM tstaff
GROUP BY depart;



# HAVING 포함

예시1

SELECT depart, ROUND(AVG(salary),2) AS 급여평균
FROM tstaff
GROUP BY depart
HAVING AVG(salary) >= 340;



예시2

SELECT depart, AVG(salary)
FROM tstaff
WHERE salary > 300
GROUP BY depart;

분명 GROUP BY는 WHERE가 쓰이면 안된다고 했는데
날 가르쳐줬던 사람도 잘 모르고 했던 말인것같다.
그러고 보면 본인이 뭘 가르칠때도 잘 모르는 사람들은
왜 해야하는지를 말해주지 않고 그냥 하라고 하더라



예시3

SELECT depart, ROUND(AVG(salary),2) AS 급여평균
FROM tstaff
WHERE salary > 300
GROUP BY depart
HAVING AVG(salary) >= 360
ORDER BY depart;

GROUP BY와 WHERE, HAVING을 쓸때는
WHERE를 통해서 먼저 필터링이 된다.
본 예시의 경우에는 WHERE 를 통해서 걸러지고 -> 평균이 산출되기 때문에
WHERE를 쓰지 않았을때 전 직원을 대상으로 평균을 산출하고 나오는 결과값에 비해서
결과값이 크다는 것을 알 수 있다.



예시4

SELECT depart, MAX(salary)
FROM tstaff
WHERE depart
IN ('인사과', '영업부')
GROUP BY depart;



예시5

SELECT depart, MAX(salary)
FROM tstaff
GROUP BY depart HAVING depart
IN ('인사과','영업부');

예시4와 예시5의 결과값은 같다.
다만 표현이 다를 뿐이다.
하지만 차이가 있다.
WHERE절을 사용한 예시4번은
WHERE로 인해서 불필요한 부분을 제거한 후에 계산을 하지만
예시5의 경우에는 모두다 계산을 한 이후에 필요없는 부분을 제거해준다.
따라서, 불필요한 연산을 줄이기 위해 WHERE를 써주는 것이 효율적이다.

300x250