본문 바로가기

Oracle/SQL

SQL 다중행 함수 - 그룹함수 (SUM) 토탈값

SUM (토탈값)

GROUP 함수의 특징 :  null 값을 무시한다.

예제 : 커미션의 토탈값을 출력

select sum(comm)
from emp;

or

select sum(nvl (comm,0))
from emp;

→ 두개의 sql 중 속도가 빠른 sql 은 무엇인가?

첫번째 sql 이 속도가 더 빠르다.

NULL 값을 무시하고 계산하기때문에 식이 줄어든다.

두번째 sql 은 null 값이 0으로 치환되어 sum 연산에 포함되어있다.

따라서 만약 데이터가 1억개 넘는다고 하면 0 을 더하는 식이 있기 때문에 연산시간이 너무 늘어나게 된다.

문제 : 직업 , 직업별 토탈월급을 출력 , 직업별토탈월급이 높은 순으로 출력

select job, sum(sal)
from emp
group by job
order by 2 desc;

문제 : 직업, 직업별 토탈월급을 출력 직업이 SALESMAN 은 제외하고 출력

select job, sum(sal) 
from emp 
where job != 'SALESMAN' 
group by job ;

문제 : 직업, 직업별 토탈월급을 출력 , 직업별 토탈월급이 5000 이상인것만 출력

select job, sum(sal) 
from emp 
where sum(sal) >= 5000 
group by job;

해당코드는 오류이다. 오류의 이유는 ?

→ 그룹함수의 값의 조건은 절은 where 절에는 사용할 수 없다. (where 절은 검색조건절이기 때문)

  sum(sal) 은 그룹함수의 값 이므로 그룹함수의값에 대한 조건을 주려면 Having 절에 주어야한다. 

→ 즉, where 절은 group 함수 외에 일반 검색 조건을 줄 때에만 하용할 수 있다는 의미. 

→ 따라서 group 절에 검색조건을 주는 방법은 having 절에 사용하는것이다.

해결 쿼리

select job, sum(sal) 
from emp 
group by job 
having sum(sal) >= 5000;

문제 : 부서번호, 부서번호별 평균월급 출력, 부서번호별 평균월급이 2000 이상인것 출력하고 부서번호별 평균월급이 높은것부터 출력하시오

select deptno, sum(sal) 
from emp 
group by deptno 
having sum(sal) >=2000 
order by sum(sal)desc;

-> 그룹함수로 묶인 sum(sal) 의 조건이기 때문에 having 절에 조건을 적었다.

 

문제 : 직업과, 직업별 토탈월급 출력하는데 세일즈맨은 제외해라, 그리고 토탈월급이 높은 순서대로 출력

select job, sum(sal)
from emp
where job ≠ 'SALESMAN'
group by job 
order by 2 desc

문제: 직업과, 직업별 토탈월급 출력하는데 토탈월급이 5000이상 출력

select job, sum(sal) 
from emp 
group by job
having sum(sal) >= 5000;

 

부서번호, 부서번호별 토탈월급 , 부서번호는 20 번 제외, 토탈월급이 2000 이상인것만 출력 부서번호별 토탈월급이 높은것부터 출력

select deptno, sum(sal) 
from emp 
where deptno not in 20 
group by deptno 
having sum(sal) >=2000 
order by 2 desc;

→ having 절에 deptno ≠ 20 을 주게되면 검색 성능이 느려지므로 where 절에 준다.


SQL 속도를 높이는 방법

  1. HAVING 절에는 일반 검색조건을 주지 않는다.

문제 : 직업, 직업별 토탈월급 출력 세일즈 맨은 제외 , 직업별 토탈월급 4000 이상만 출력 하고 높은 순대로 출력하며 천단위를 부여하시오

select job, to_char(sum(sal), '999,999') from emp where job != 'SALESMAN' group by job having sum(sal) >=4000 order by sum(sal) desc

select deptno, sum(sal) 
from emp 
where deptno not in 20 
group by deptno 
having sum(sal) >=2000 
order by 2 desc;

 

문제  : 부서번호, 직업, 부서번호별 직업별 토탈월급을 출력

select deptno, job, sum(sal)
from emp 
group by deptno, job
order by deptno, job;

→ 그동안에 group by 절에 컬럼을 한가지만 작성했었는데, 위와같이 group by 절에 컬럼을 여러개를 사용할 수 있다.

group by 절에 여러개의 컬럼이 있다는건 select 절에도 컬럼이 여러개 있다는 뜻이다.

select 절에 있는 컬럼들 ,그룹컬럼 제외한 컬럼들에 그룹바이 절에 써 주어야 오류가 나지 않는다.