ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SQL 그룹함수, Group by, Having 조건식
    Data Base_Oracle/SQL 2020. 1. 4. 15:14

    그룹함수

    여러개의 행에 대해 하나의 행으로 결과를 반환하는 함수,
    통계에 관련된 함수 : 최대값, 최소값, 평균, 총레코드수, 합계 등

    함수 설명
    count() 해당 필드의 레코드 수를 반환하는 함수,
    각 열마다 값이 있으면 1, 없으면 0을 반환
    count( * ) : null을 포함한 필드의 레코드 수(열 수), 주로 사용됨
    or count(필드명) : null을 포함하지 않음
    min() 필드의 최소값을 반환하는 함수
    max() 필드의 최대값을 반환하는 함수
    avg() 필드의 평균을 반환하는 함수
    sum() 필드의 합계를 반환하는 함수
    .... 통계에 더욱 깊은 관련이 있는 함수들도 있음
    분산, 표준편차 등

    그룹함수 사용례

    { count() }

    ▷ emp테이블에서 급여가 3000이상인 사원의 수 구하기

    ▶ [ SQL> select count(*) from emp where sal>=3000; ]

    count( * )
    3

    { avg() max() min() sum() }

    ▷ emp테이블에서 필드의 총 레코드수, 급여의 평균(소수점 탈락), 최대값, 최소값을 구하고 급여의 총합계 앞에
    달러기호($)를 붙인 뒤 3자리마다 콤마(,)를 표기

    ▶ [ SQL> select count( * ), trunc(avg(sal)), max(sal), min(sal), to_char(sum(sal), '$999,999') from emp; ]

    COUNT( * ) TRUNC(AVG(SAL)) MAX(SAL) MIN(SAL) TO_CHAR~
    14 2073 5000 800 $29,025

    ※ Min(), Max()_문자, 날짜 데이터 계산 ※

    ▷ emp테이블에서 이름, 날짜, 급여의 최소/최대값 조회

    ▶ [ SQL> select min(ename), max(ename), min(hiredate), max(hiredate), min(sal), max(sal) from emp; ]

    MIN(ENAME) MAX(ENAME) MIN(HIREDATE) MAX(HIREDATE) MIN(SAL) MAX(SAL)
    ADAMS WARD 80/12/17 87/05/23 800 5000

    ※ 알파벳은 A ~ Z순으로 크기를 계산할 수 있고,
    날짜는 현재에 가까울수록 큰 값으로 처리됨

    Group by 

    # 예제_에러

    ▶ emp테이블에서 이름, 필드의 총 레코드수, 급여의 평균(소수점 탈락), 최대값, 최소값을 구하고 급여의 총합계 앞에 달러기호($)를 붙인 뒤 3자리마다 콤마(,)를 표기
    [ SQL> select ename, count( * ), trunc(avg(sal)), max(sal), min(sal), to_char(sum(sal), '$999,999') from emp;
    ORA-00937: 단일 그룹의 그룹 함수가 아닙니다 ]

    ※ select ~ from 사이에 그룹함수는 일반 필드와 같이 사용할 수 없음
    ename : 일반필드, count( * ) ~ : 그룹함수

    ∴ 일반필드를 그룹함수와 성격이 갖도록 설정해야함

    § 형식

    [ SQL> select 필드,,, 그룹함수,,,
    from 테이블명
    where 조건식
    group by 그룹을 지워줄 필드명
    order by 필드명 ; ]

    # 풀이

    ▶ [ SQL> select ename, count( * ), trunc(avg(sal)), max(sal), min(sal), to_char(sum(sal), '$999,999')
    from emp group by ename;

    ENAME COUNT( * ) TRUNC(AVG(SAL)) MAX(SAL) MIN(SAL) TO_CHAR~
    ALLEN 1 1600 1600 1600 $1,600
    JONES 1 2975 2975 2975 $2,975
    ... ... ... ... ... ..

    ※ 그룹함수가 각각의 레코드에 적용된 값이 표출되기 때문에 원래의 sal값과 차이가 없음

    그룹함수 중첩

    • max(avg(~)) : 평균의 최대값을 산출

    • max(sum(~)) : 합계의 최대값 산출

    • min(sum(~)) : 합계의 최소값 산출

      ※ 그룹함수는 한 번만 중첩이 가능함

    # 예제

    ▷ emp테이블에서 부서번호별로 급여 평균의 최대값, 급여합계의 최대값, 급여합계의 최소값, 급여가 가장 높은 사람의 급여를 출력

    ▶ [ SQL> select max(avg(sal)), max(sum(sal)), min(sum(sal)), max(max(sal))
    from emp
    group by deptno; ]
    ※ 그룹함수 중첩시에는 group by에 일반필드를 선언해도
    일반필드와 그룹함수의 결과를 동시에 표출할 수 없음

    MAX(AVG(SAL)) MAX(SUM(SAL)) MIN(SUM(SAL)) MAX(MAX(SAL))
    2916.6667 10875 8750 5000

    Having 조건식

    그룹함수 조건식
    그룹함수를 이용해서 조건식을 작성하는 경우에 필요함

    # 에러

    ▷ emp테이블에서 부서별로 사원의 수가 4명이상인 부서의 사원 정보를 찾아서
    부서번호, 급여의 합계를 출력

    ▶ [ SQL> select deptno, sum(sal) as 급여합계 from emp
    where count( * ) >= 4
    group by deptno;
    1행에 오류: ORA-00934: 그룹 함수는 허가되지 않습니다 ]

    ※ where 조건식은 일반적인 검색을 할 때 사용, 그룹 함수 사용 불가 ※

    § 형식

    [ SQL> select ~ from ~ where ~ group by ~ having 조건식 order by ~ ]

    # 풀이

    ▷ emp테이블에서 사원의 수가 4명 이상인 부서의 급여합계를 구하고,
    급여합계가 높은 순으로 정렬

    ▶ [ SQL> select deptno, sum(sal) as 급여합계 from emp
    group by deptno
    having count( * ) >= 4
    order by sum(sal) desc; ]

    DEPTNO 급여합계
    20 10875
    30 9400

    # 예제

    ▷ emp테이블에서 업무가 MANAGER가 아닌 사원들에 대해
    부서별로 급여의 합이 2500이상인 부서의 정보를 출력
    부서번호, 급여 합계순으로 출력, 급여 합계가 높은 순으로 정렬

    ▶ [ SQL> select deptno, sum(sal) "부서별 급여합계" from emp
    where job !='MANAGER'
    group by deptno
    having sum(sal) >= 2500
    order by 2 desc; ]

    DEPTNO 부서별 급여합계
    20 7900
    30 6550
    10 6300

    그룹함수에는 group by나 having과 같이 일반필드와는 다른 구문이나 조건들이 필요하기 때문에 따로 익혀두는 것이 필요합니다.

    댓글

Designed by Tistory.