DB_SQL_다중행함수02

BBBeom·2022년 8월 11일

DB

목록 보기
15/18

GROUP BY절

각 부서별 평균 급여를 구하기 위해 제작한
각 SELECT문의 결과값을 하나로 통합해보자

10번 부서 급여의 총합
20번 부서 급여의 총합
30번 부서 급여의 총합

SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 10;
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 20;
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 30;

SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 10
UNION ALL
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 20
UNION ALL
SELECT AVG(SAL) FROM EMP WHERE DEPTNO = 30;

SELECT DEPTNO, AVG(SAL) FROM EMP
GROUP BY DEPTNO
ORDER BY DEPTNO ASC;
  • 문법

SELECT
FROM
WHERE
GROUP BY 그룹화할 열을 지정, 여러개 지정 가능
ORDER BY 정렬하려는 열을 지정

/*부서 번호 및 직책별 평균 급여를 출력*/
SELECT DEPTNO, JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO ASC, JOB ASC;		/*ORDER BY 정렬의 기본값은 ASC(오름차순)다 생략가능*/

두가지 이상을 묶을때는 앞에 나오는 DEPTNO를 먼저 묶고
그다음 JOB를 묶는다

그룹을 묶을때는 큰 카테고리의 데이터(겹치는게 많은데이터)대로 묶었을때 트리형태처럼 나온다
출력문에는 전부다 나오지만 그룹형식으로 묶는다는 개념적인 부분으로 생각하면
점점 갈래가 늘어나는 형태다

     -3
1-2-3
  -2-3
     -3

     -3
2-1-3
2-1-3
     -3

SELECT DEPTNO, JOB, ENAME,AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO ASC, ENAME ASC;  /*ENAME은 그룹으로 안묶여서 정렬이 불가능 하다*/

DISTINCT 와 기능적으로 유사하다 차이점을 확실히 알고 각 상황에 맞게 사용하자
DISTINCT -> 중복된 데이터를 정렬하지 않고 제외후 출력
GROUP BY -> 중복된 데이터를 정렬하고 제외후 출력 + 각종함수로 다양한 결과값 출력가능
HAVING절의 유무 차이도 크다고 생각한다

HAVING

SELECT DEPTNO, JOB, AVG(SAL)	/*AVG는 다중행 함수다*/
FROM EMP;
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000 /*출력그룹의 제한을 걸수 있다*/
ORDER BY DEPTNO, JOB;

AVG는 그룹으로 묶이지않은 출력값이다
이값을 HAVING 뒤에 조건을 걸어서 출력받을수있다
WHERE와 헷갈릴 수 있는데 정확히 그룹으로 묶이지 않은 출력값만 조건을 걸수 있다는거 기억해야한다
(예시에선 AVG(SAL)이 HAVING의 조건을 수행한다)

GROUP BY 절을 사용해 그룹화된 결과중
출력그룹을 선별하는 조건은 별칭이 불가하다

  • WHERE 절

    • 같은점 : 지정한 조건식이 참인 결과만 출력
    • 다른점 : SELECT절의 모든값을 대상으로 출력대상의 행을 제한
  • HAVING 절

    • 같은점 : 지정한 조건식이 참인 결과만 출력
    • 다른점 : GROUP BY 절의 그룹화된 값을 대상으로 출력대상의 행을 제한
/*부서별 직책별의 평균급여가 500이상인 사원들의
부서번호, 직책, 부서별 직책의 평균급여를 출력*/
SELECT DEPTNO , JOB, AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 500
ORDER BY DEPTNO;
SELECT JOB, DEPTNO, AVG(SAL)
FROM EMP
GROUP BY JOB
HAVING AVG(SAL) >= 500
ORDER BY JOB;
/*이걸 할수 없는건 JOB를 그룹하고 DEPTNO와 AVG(SAL)은 다중행이면서 같은 행이 아니다
따라서 단일행과 다중행을 함께 표현할수 없는것처럼 다중행과 다중행이여도 행의 갯수가
다르면 출력이 불가능하다*/

GROUP BY 절에서만 사용가능한 특수 함수

그룹화 데이터의 합계를 출력할때 사용
1. ROLLUP 함수
2. CUBE 함수

SELECT DEPTNO, JOB, 
COUNT(*), MAX(SAL), MIN(SAL), SUM(SAL), AVG(SAL)
FROM EMP
GROUP BY DEPTNO, JOB
ORDER BY DEPTNO, JOB;
SELECT DEPTNO, JOB, 
COUNT(*), MAX(SAL), MIN(SAL), SUM(SAL), ROUND(AVG(SAL))
FROM EMP
GROUP BY ROLLUP(DEPTNO, JOB);

각 데이터들의 통계를 알려준다
부서와 직책별로 나누면 부서가 좀더 큰개념이라 중복되기도 한다
그 큰개념을 기준으로 한번더 그룹별로 묶은 통계를 내준다

ROLLUP(A,B,C)

A그룹별 B그룹별 C그룹별에 해당하는 결과 출력
A그룹별 B그룹별 에 해당하는 결과 출력
A그룹별 에 해당하는 결과 출력
전체 데이터 결과 출력

A와 B가 그룹이 되면 앞에 있는 A를 기준으로 한번 더 묶음이 가능해진다
그룹별로 묶다보면 결국에 출력하면 또 중복되는 값이 생기는데
그 중복을 ROLLUP으로 묶어서 통계를 낼수있다

SELECT DEPTNO, JOB, 
COUNT(*), MAX(SAL), MIN(SAL), SUM(SAL), ROUND(AVG(SAL))
FROM EMP
GROUP BY CUBE(DEPTNO, JOB);

CUBE(A,B,C)

롤업이 A를 기준으로 한번더 묶었다면
큐브는 모든 경우의수를 기준으로 묶는다
A와 B의 순서가 바뀌더라도 A,B 둘중 더 많은 경우의 수로 묶기때문에
출력값이 항상 같다

롤업은 A기준이때문에 B그룹이 A그룹보다 행이 많으면
B의 그룹별 통계가 손실이 나는 경우가 생기는데
CUBE는 자동으로 행이 많은 그룹을 기준으로 최대한 많은 데이터 묶는

profile
BackEnd_BasketBall_Beom

0개의 댓글