# TIL - 2026.08.26

ssls·약 8시간 전

📌 오늘 학습한 주제

  • 그룹화 및 집계 제어 (GROUP BY, HAVING, WITH ROLLUP)
  • 윈도우 분석 함수 (RANK, DENSE_RANK, ROW_NUMBER over PARTITION BY / ORDER BY)
  • 다양한 테이블 결합 (INNER JOIN, Non-Equi JOIN, LEFT/RIGHT OUTER JOIN, Self JOIN)
  • 서브쿼리 및 존재 검사 연산자 (EXISTS), 학사 DB 추가 실습 문제

💡 오늘 배운 것 — 나만의 언어로

① 오늘의 목표

  • GROUP BYHAVING을 활용한 그룹별 통계 연산 및 윈도우 함수를 마스터하고, 다중 테이블 간 관계를 조인(INNER/OUTER/Self JOIN)하여 복합 비즈니스 데이터를 조회하기

② 학습할 내용

  • 그룹 집계 및 소계 (GROUP BY, HAVING, WITH ROLLUP):
    • 그룹화된 데이터에 조건을 적용할 때는 WHERE가 아닌 HAVING 절을 사용해야 함을 익혔다.
    • WITH ROLLUP을 적용해 다차원 그룹핑 시 중간 소계 및 총합계를 자동으로 도출했다.
  • 윈도우 분석 함수: 기존 행의 구조를 유지하면서 순위나 그룹별 통계를 계산하는 RANK(), DENSE_RANK(), ROW_NUMBER()AVG() OVER(PARTITION BY ...)의 활용법을 다루었다.
  • 다양한 JOIN 기법:
    • INNER JOIN: ON 조건식 또는 USING(컬럼명)을 이용한 일치 데이터 결합 및 다중 테이블 연쇄 조인.
    • Non-Equi JOIN: 동등 조건(=)이 아닌 범위(BETWEEN)를 활용한 급여 등급 매핑.
    • OUTER JOIN: 매핑되지 않는 데이터(부서 미배치 사원 등)까지 누락 없이 보존하는 LEFT OUTER JOIN.
    • Self JOIN: 동일 테이블(employee) 내에서 사원과 사수(MGR_ID = EMP_ID) 관계 조회.

💻 오늘 핵심 코드

1. 그룹화 집계, HAVING 및 ROLLUP

-- 부서별 급여 총액이 9,000,000 이상인 부서 필터링 (HAVING)
SELECT  DEPT_ID,
        SUM(SALARY) AS `부서 총급여`
FROM    employee
GROUP BY DEPT_ID 
HAVING  SUM(SALARY) >= 9000000;

-- 년도 및 학기별 평점과 소계/총계 산출 (WITH ROLLUP)
SELECT  SUBSTRING(TERM_NO, 1, 4) AS `년도`,
        SUBSTRING(TERM_NO, 5, 2) AS `학기`,
        ROUND(AVG(POINT), 1)     AS `평점`
FROM    tb_grade
WHERE   STUDENT_NO = 'A112113'
GROUP BY SUBSTRING(TERM_NO, 1, 4), SUBSTRING(TERM_NO, 5, 2) WITH ROLLUP;

2. 윈도우 함수 (순위 및 부서별 순위)

-- 1. 전체 사원 급여 순위
SELECT  EMP_NAME,
        SALARY,
        RANK() OVER(ORDER BY SALARY DESC)       AS `RANK`,
        DENSE_RANK() OVER(ORDER BY SALARY DESC) AS `DENSE_RANK`,
        ROW_NUMBER() OVER(ORDER BY SALARY DESC) AS `ROW_NUMBER`
FROM    employee;

-- 2. 부서별 파티션 급여 순위
SELECT  EMP_NAME,
        DEPT_ID,
        SALARY,
        RANK() OVER(PARTITION BY DEPT_ID ORDER BY SALARY DESC) AS `부서내 순위`
FROM    employee;

3. 다중 조인, Non-Equi JOIN 및 Self JOIN

-- 다중 테이블 조인 및 Non-Equi JOIN (급여 등급 매핑)
SELECT  E.EMP_NAME,
        J.JOB_TITLE,
        D.DEPT_NAME,
        L.LOC_DESCRIBE,
        C.COUNTRY_NAME,
        S.SLEVEL
FROM    job J
JOIN    employee   E ON(J.JOB_ID = E.JOB_ID)
JOIN    department D ON(E.DEPT_ID = D.DEPT_ID) 
JOIN    location   L ON(L.LOCATION_ID = D.LOC_ID)
JOIN    country    C ON(L.COUNTRY_ID = C.COUNTRY_ID) 
JOIN    sal_grade  S ON(E.SALARY BETWEEN S.LOWEST AND S.HIGHEST)
WHERE   DEPT_NAME LIKE '해외%' AND LOC_DESCRIBE LIKE '아시아%'
ORDER BY S.SLEVEL DESC;

-- Self JOIN: 사원 - 사수 - 상위 사수 계층 조회
SELECT  E.EMP_NAME AS `사원명`,
        M.EMP_NAME AS `사수명`,
        S.EMP_NAME AS `상위사수명`
FROM        employee E
LEFT JOIN   employee M ON (E.MGR_ID = M.EMP_ID)
LEFT JOIN   employee S ON (M.MGR_ID = S.EMP_ID);

🛠️ 실습 / 결과물 & 참고 자료

③ 실습 / 결과물

  • 강의 실습코드: MySQL lgcns, SQLDB 환경에서 GROUP BY, HAVING, WITH ROLLUP, 윈도우 함수, 다중/외부/자체 조인 및 학사 워크북 실습 완료.

④ 참고 자료


🔍 문제와 해결

  • 막힌 부분: 그룹 집계 결과에 조건을 걸 때 WHERE 절에 SUM(SALARY) 집계 함수를 직접 넣어 구문 오류가 발생하거나, LEFT JOIN 시 부서가 없는 사원이 누락되는 현상 점검.
  • 해결 방법: 그룹 집계 조건은 반드시 HAVING 절에 작성하고, 기준 테이블의 모든 행을 보존하기 위해 LEFT OUTER JOINIS NULL 필터링을 조합하여 해결함.

🎯 다음에 할 일

  • 상관 서브쿼리(Correlated Subquery) 및 인라인 뷰(Inline View) 패턴 분석하기
  • DDL/DML 트랜잭션(COMMIT, ROLLBACK) 및 인덱스(Index) 최적화 기법 학습하기
profile
성장중

0개의 댓글