프로그래밍 언어 공부/SQL

4. 다중행 함수와 데이터 그룹화(GROUP BY)

성균관_해태 2021. 10. 15. 19:01

1. 다중행 함수(SUM, COUNT,AVG,MAX,MIN)

  • 한 열에 대해서 연산을 수행해주는 함수들이다. 이름처럼 합, 개수, 평균, 최대/최소 등을 계산하여 조회한다.
    ## 기본 구조
    SELECT SUM(열), COUNT(열), AVG(열), MIN(열),MAX(열) FROM TABLE;
    
    ## 주의사항
    # 다중행 함수는 기본적으로 DISTINCT가 적용 안된 ALL을 기반으로 계산된다.
    # 만약 DISTINCT를 고려하고 싶으면 파라미터 안에 DISTNCT를 넣어주면 된다.
    SELECT SUM(DISTINCT 열), COUNT(DISTINCT 열) FROM TABLE;​

2. 결과 값을 원하는 열로 묶어 출력하는 GROUP BY절

2-1. 기본 형태

  • 파이썬과 R에서의 GROUPBY와 동일한 작업을 수행하는 절이다.
  • FROM 절 이후(WHERE이 있다면 WHERE 이후)에 작성하면 된다. 
    • SELECT [ ] 
    • FROM [ ]
    • GROUP BY [ ]
    • ORDER BY [ ]
## 기본 형태
SELECT SUM(SAL), GROUP
FROM TABLE
WHERE GROUP IN ('10','20','30','40')
GROUP BY GROUP;

2-2. GROUPBY의 조건을 주는 HAVING 절

  • GROUPBY에서 조건을 줄 때는 WHERE이 아닌 HAVING절을 따로 사용한다.
  • 만약 WHERE과 HAVING을 같이 쓰게 되면, WHERE로 1차적으로 걸러진 데이터에 GROUPBY-HAVING이 들어가는 것이다. 주의해야 한다!
## 기본 형태 예시
SELECT DEPTNO, JOB, AVG(SAL) FROM EMP
(WHERE SAL >= 2000) ## 중간에 WHERE이 들어가면, 1차적으로 데이터를 거른 후에 GROUPBY 수행
GROUP BY DEPTNO, JOB
HAVING AVG(SAL) >= 2000 ## AVG(SAL)이 2천 이상인 것만 반환
ORDER BY JOB;

2-3. 그룹화와 관련된 여러 함수(ROLLUP, CUBE, GROUPING SETS 등)

  • 코테가 급하니 나중에 작성~!!!!!!

 

3. 문제 풀이

3-1. 문제1

  • 조건1 : 평균 급여를 출력할 때 소수점을 제외하고, 각 부서 번호별로 출력
    ## 내 풀이
    SELECT DEPTNO, 
    TRUNC(AVG(SAL),0) AS AVG_SAL,
    MAX(SAL) AS MAX_SAL,
    MIN(SAL) AS MIN_SAL,
    COUNT(SAL) AS CNT
    FROM EMP
    GROUP BY DEPTNO;
    
    ## 정답
    SELECT DEPTNO,
           TRUNC(AVG(SAL)) AS AVG_SAL,
           MAX(SAL) AS MAX_SAL,
           MIN(SAL) AS MIN_SAL,
           COUNT(*) AS CNT
      FROM EMP
    GROUP BY DEPTNO;​
  • 만약 소수점을 없앤다면, TRUNC 함수를 사용하면 된다!

3-2. 문제2

  • 조건 : 같은 직책에 종사하는 사원이 3명 이상인 직책과 인원수를 출력
## 내 답안
SELECT JOB, COUNT(*)
FROM EMP
GROUP BY JOB
HAVING COUNT(*) >=3;

## 정답
SELECT JOB,
       COUNT(*)
  FROM EMP
GROUP BY JOB
HAVING COUNT(*) >= 3;

3-3. 문제3

## 내 답안
SELECT TO_CHAR(HIREDATE,'YYYY') AS HIRE_YEAR
DEPTNO, COUNT(*) FROM EMP
GROUP BY TO_CHAR(HIREDATE,'YYYY'), DEPTNO;

## 정답
SELECT TO_CHAR(HIREDATE, 'YYYY') AS HIRE_YEAR,
       DEPTNO,
       COUNT(*) AS CNT
  FROM EMP
GROUP BY TO_CHAR(HIREDATE, 'YYYY'), DEPTNO;

 

3-4. 문제4

## 내 답
SELECT NLV2(TO_CHAR(COMM),"O","X") AS EXIST_COMM, COUNT(*) FROM EMP
GROUP BY NLV2(TO_CHAR(COMM),"O","X");

## 실제 답안
SELECT NVL2(COMM, 'O', 'X') AS EXIST_COMM,
       COUNT(*) AS CNT
  FROM EMP
GROUP BY NVL2(COMM, 'O', 'X');
  • 어차피 전부 NVL2로 바꿔주는거라, TO_CHAR가 필요 없을 수도 있는 것 같다!

3-5. 문제5

  • CUBE, ROLLUP, 등을 묻는 문제라 일단 PASS