inblog logo
|
jjack1
    데이터베이스MySQL

    [DB] 10. 통계 쿼리 함수들

    최재원's avatar
    최재원
    Mar 02, 2025
    [DB] 10. 통계 쿼리 함수들
    Contents
    1. RANK() OVER() 함수1. rank() over(order by)2. 직접 순위를 지정 + 변수 생성 방법3. partition 파티션 사용 rank() over(partition by)2. ROLLUP1. union all을 사용한 집계2. rollup를 사용해 해결3. Pivot1. cal 테이블로 연습2. emp 테이블 피봇 해보기

    1. RANK() OVER() 함수

    ❗
    순위를 매길 수 있는 함수
    • rank() over()
    • dense_rank() over()
    • row_number() over()
    ❓
    emp 테이블에서, 본인의 월급과 상사의 월급의 합의 순위를 내림차순으로 구하시오

    1. rank() over(order by)

    select 직원명, 직원월급, 상사이름, 상사월급, 합계, rank() over(order by 합계 desc) '순위' from ( select e1.ename '직원명', e1.sal '직원월급', e2.ename '상사이름', e2.sal '상사월급', e1.sal + ifnull(e2.sal, 0) '합계' from emp e1 left outer join emp e2 on e1.mgr = e2.empno )s;
    notion image
    • select절 안에 다 작성할 때
    select e1.ename '직원', e1.sal '월급', e2.ename '상사', e2.sal '월급', e1.sal + ifnull(e2.sal, 0) '합계', rank() over(order by e1.sal + ifnull(e2.sal, 0) desc) '순위' from emp e1 left outer join emp e2 on e1.mgr = e2.EMPNO;

    2. 직접 순위를 지정 + 변수 생성 방법

    • set 을 사용해서 변수를 만들 수 있음
    set @rownum := 0; select *, @rownum := @rownum + 1 from ( select ename, sal from emp order by sal desc ) t;
    • 정렬을 한 다음 숫자를 붙인다.
    notion image

    3. partition 파티션 사용 rank() over(partition by)

    • partition은 group by와 비슷한 방식
    • group by는 그룹 별 세로 연산
    • partition은 묶음 별 순서를 매길 때 사용
    • 지정한 컬럼에 값을 묶어서 표현한다.
    ❓
    부서 별 월급 순위를 구하시오
    select deptno, ename, sal from emp where deptno = 10 union all select deptno, ename, sal from emp where deptno = 20 union all select deptno, ename, sal from emp where deptno = 30 order by deptno, sal desc;
    ⬇⬇⬇⬇⬇
    select deptno, ename, sal, rank() over(partition by deptno order by sal desc) '순위' from emp order by deptno;
    notion image
    • 나이 별 키 순위를 나타내라
    select name, height, 나이, rank() over(partition by 나이 order by height desc) '키_순위' from ( select name, height, 2025 - substr(birthday,1,4) '나이' from student order by 나이 desc ) t;
    notion image

    2. ROLLUP

    ❗
    ROLLUP은 그룹별 소계를 자동으로 계산하는 기능입니다.
    즉, GROUP BY와 함께 사용하면 부분 합계(소계)와 전체 합계를 자동으로 추가할 수 있습니다.
    계층적 데이터 요약
    notion image

    1. union all을 사용한 집계

    1. 테이블 확인

    select * from emp
    notion image

    2. job이 CLERK인 데이터 추출

    select * from emp where job = 'CLERK';
    notion image

    3. job, deptno, sal 만 추출

    select job, deptno, sal from emp where job = 'CLERK';
    notion image

    4. deptno별 sal평균, 인원수를 추출

    select job, deptno, avg(sal), count(*) from emp where job = 'CLERK' group by deptno;
    notion image

    5. job별 sal의 평균, 인원수의 합계

    select job, null deptno, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by job;
    notion image

    6. 4번과 5번 테이블의 집합

    select job, deptno, avg(sal), count(*) from emp where job = 'CLERK' group by deptno union all select job, null deptno, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by job;
    notion image

    7. 다른 직업도 추가

    select job, deptno, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'SALESMAN' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'SALESMAN' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'MANAGER' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'MANAGER' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'ANALYST' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'ANALYST' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'PRESIDENT' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'ANALYST' group by job;
    notion image

    8. 모든 직업의 sal평균, 인원수

    select null job, null deptno, avg(sal) avg, count(*) cnt from emp;
    notion image

    9. 최종테이블

    select job, deptno, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'CLERK' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'SALESMAN' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'SALESMAN' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'MANAGER' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'MANAGER' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'ANALYST' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'ANALYST' group by job union all select job, deptno, avg(sal), count(*) from emp where job = 'PRESIDENT' group by deptno union all select job, null, avg(sal) avg, count(*) cnt from emp where job = 'PRESIDENT' group by job union all select null job, null deptno, avg(sal) avg, count(*) cnt from emp;
    notion image

    2. rollup를 사용해 해결

    select job, deptno, avg(sal), count(*) cnt from emp group by job, deptno with rollup;
    notion image

    3. Pivot

    ❗
    행 데이터를 열로 변환하여 요약 보고서를 생성하는 기법
    notion image
    notion image

    1. cal 테이블로 연습

    week 데이터가 없을 경우
    1 / 7 = ceil(0.x) 1 2 / 7 = ceil(0.x) 1 3 / 7 = ceil(0.x) 1 4 / 7 = ceil(0.x) 1 5 / 7 = ceil(0.x) 1 6 / 7 = ceil(0.x) 1 7 / 7 = ceil(0.x) 1 8 / 7 = ceil(0.x) 2 9 / 7 = ceil(0.x) 2 . . . . .
    day로 week값을 만들어 사용한다.

    1. 달력 테이블 확인

    select * from cal;
    notion image

    2. 컬럼으로 만들고 싶은 day 데이터 확인

    select distinct day from cal;
    notion image

    3. day를 피봇형태로 만들어 보기

    select '일','월','화','수','목','금','토' from cal;
    notion image

    4. week를 기준으로 값을 출력하기

    notion image
    1. 전체 week별 달력 그려보기
    select week, '일', '월', '화', '수', '목', '금', '토' from cal group by week;
    notion image
    1. select 마다 행 표기 방법
    select 1 'week', 1 '일' union all select 2 'week', 8 '일';
    notion image
    1. group by 로 week별 계산
    notion image
    • 1 week를 그룹바이로 묶었기 때문에 맨 왼쪽 1를 압축 한다
    • 그렇다면 1~7의 값중 1개의 값만 나와야 한다
    • 표기하고 싶은 요일별 값 1개만 나오게 하자
    • 예) 일요일이라면 숫자 1만 남겨야 한다
      • group by 함수중 sum(), max() 둘중 하나를 사용해 1만 남게 하자
    • day를 압축 할 수 있도록 요일에 해당하면 그 값을 넣고 아니면 0을 넣어보자
    select week, day, num_day, if(day= '일', num_day,0) '일요일' from cal where week = 1;
    notion image
    • week컬럼과 요일 값 컬럼만 표기하자
    select week, if(day= '일', num_day,0) '일요일' from cal where week = 1;
    notion image
    select week, if(day= '월', num_day,0) '월요일' from cal where week = 1;
    notion image
    • group by 로 압축해보자
    select week, max(if(day= '일', num_day,0)) '일요일' from cal where week = 1 group by week;
    notion image
    select week, max(if(day= '월', num_day,0)) '월요일' from cal where week = 1 group by week;
    notion image
    • where을 제거하고 그룹별로 표기하자
    select week, max(if(day= '일', num_day,0)) '일요일' from cal group by week;
    notion image
    • 다른 요일도 붙여보자
    select week, max(if(day='일', num_day, 0)) '일', max(if(day='월', num_day, 0)) '월', max(if(day='화', num_day, 0)) '화', max(if(day='수', num_day, 0)) '수', max(if(day='목', num_day, 0)) '목', max(if(day='금', num_day, 0)) '금', max(if(day='토', num_day, 0)) '토' from cal group by week;
    notion image

    2. emp 테이블 피봇 해보기

    select * from emp;
    notion image
    • deptno, job 컬럼만 추출
    select deptno, job from emp;
    notion image
    • job컬럼에 데이터가 어떤 종류가 있는지 확인
    • 해당 데이터들을 컬럼으로 만듦
    select distinct job from emp;
    notion image
    • 10번 부서에 직업이 어떤게 있나 확인
    select deptno, job from emp where deptno = 10;
    notion image
    • 각 직업에 인원이 있으면 숫자 1 아니면 0 으로 표기
    select deptno, if(job = 'CLERK',1,0) 'CLERK' from emp where deptno = 10;
    notion image
    • group by로 표기
    select deptno, sum(if(job = 'CLERK',1,0)) 'CLERK' from emp where deptno = 10 group by deptno;
    notion image
    • where을 제거하고 그룹별 직업 인원수 확인
    select deptno, sum(if(job = 'CLERK',1,0)) 'CLERK' from emp group by deptno;
    notion image
    • 다른 직업 추가해서 확인하기
    select deptno, sum(if(job = 'CLERK',1,0)) 'CLERK', sum(if(job = 'SALESMAN',1,0)) 'SALESMAN', sum(if(job = 'MANAGER',1,0)) 'MANAGER', sum(if(job = 'ANALYST',1,0)) 'ANALYST', sum(if(job = 'PRESIDENT',1,0)) 'PRESIDENT' from emp group by deptno;
    notion image
     
    Share article

    jjack1

    RSS·Powered by Inblog