SQL 집단함수와 GROUP BY 절, HAVING 절 정리
집단 함수
검색 결과의 합이나 개수 등 요약 정보를 제공하는 함수로 COUNT, SUM, MAX, MIN, AVG 가 있다.
- 집단 함수는 SELECT 절 만이 아닌 WHERE 절에도 올 수 있다.
- 일반적으로 집단 함수는 null 값은 제외하고 계산한다.
- 만약 전체가 null 이면 null 값을 돌려주지만 COUNT인 경우에는 0을 돌려준다.
사용 예시
1. 직원의 급여 합, 급여 최대값, 급여 최솟값, 급여 평균을 검색하라
SELECT SUM(Salary), Max(Salary), MIN(Salary), AVG(Salary)
FROM EMPLOYEE;
2. 직원의 수를 검색하라
SELECT COUNT(*)
FROM EMPLOYEE;
3. 급여 종류의 수를 검색하라
SELECT(DISTINCT Salary)
FROM EMPLOYEE;
GROUP BY
특정 애트리뷰트 값에 대해 그룹을 만드는 역할을 한다. 이렇게 만들어진 그룹에도 집단 함수를 적용 할 수 있다.
만약 값에 null 이 있다면 null을 한 그룹으로 묶는 것이 아닌 하나하나 그룹이 만들어진다.
SELECT 절에 나올 수 있는 애트리뷰트는 GROUP BY 절에 있는 애트리뷰트나 집단 함수만 올 수 있다.
사용 예시
1. 부서에 대하여 부서 번호, 부서마다 직원 수, 부서마다 평균 급여를 검색하라.
SELECT Dno, COUNT(*), AVG(SALARY)
FROM EMPLOYEE
GROUP BY Dno;
2. 프로젝트에 대해서 프로젝트 번호, 프로젝트 이름, 프로젝트에서 일하는 직원의 수를 검색하라.
SELECT Pnumber, Pname, COUNT(*)
FROM PROJECT, WORKS_ON
WHERE Pnumber=Pno
GROUP BY Pnumber, Pname;
HAVING
그룹을 필터링하는 절이다.
HAVING 절에는 GROUP BY절에 있는 애트리뷰트나 집단 함수만 올 수 있다.
사용 예시
1. 직원이 2명 이상 참여한 프로젝트에 대하여 프로젝트 번호, 프로젝트 이름, 참여한 직원의 수를 검색하라.
SELECT Pnumber, Pname, COUNT(*)
FROM PROJECT, WORKS_ON
WHERE Pnumber = pno
GROUP BY Pnumber, Pname
HAVING COUNT(*) > 2;
=> 조건 절이 WHERE 와 HAVING 2개 이기 때문에 어느 절에 어느 조건이 들어가야 할 지 잘 판단해야 한다.
WHERE 절이 먼저 적용되고 HAVING 절이 나중에 적용된다.
2. 각각의 프로젝트에 대하여 5번 부서에서 일하는 직원의 프로젝트 번호, 프로젝트 이름과 직원 수를 검색하라.
SELECT Pnumber, Pname, COUNT(*)
FROM PROJECT, WORKS_ON, EMPLOYEE
WHERE Pnumber=Pno AND Ssn=Essn AND Dno=5
GROUP BY Pnumber, Pname;
3. 근무하는 부서의 직원수가 3명 이상인 부서에 대해서 각 부서에서 연봉이 40000이 넘는 직원들의 총 수를 검색하라.
SELECT Dno, COUNT(*)
FROM EMPLOYEE
WHERE Salary > 40000
GROUP BY Dno
HAVING COUNT(*) > 3;
=> 이렇게 생각할 수 있겠지만 WHERE 절이 먼저 적용되기 때문에 COUNT(*) 값이 왜곡이 생겨버린다. 따라서 두 조건 모두 WHERE 절에 들어 가는 것이 맞다.
SELECT Dno, COUNT(*)
FROM EMPLOYEE
WHERE Salary>40000 AND
Dno IN (SELECT Dno FROM EMPLOYEE GROUP BY DNO HAVING COUNT(*) > 3)
GROUP BY Dno;
=> 중첩 쿼리를 사용하여 두 조건 모두 WHERE 절에 작성하였다.