본문 바로가기
Computer Science & Engineering/Oracle

[SQL_오라클] GROUP QUERY

by Mr.꾸 2022. 6. 10.
반응형

[SQL_오라클] GROUP QUERY

DISTINCT

  1. 만약 department_id는 유일한 값이 아니고, employee_id는 유일한 값이라고 한다면 SELECT DISTINCT department_id, employee_id라는 것은 department_id와 employee_id의 조합에 대한 값을 반환하게 된다. DISTINCT나 ALL은 바로 뒤의 하나에 대해서만 적용되는 것이 아니라 SELECT 절 전체에 적용이 된다.
  2. DISTINCT employee_id, DISTINCT first_name
    이것은 오류를 발생시킨다. 결과로 나온 테이블에서 이미 employee_id로 DISTINCT를 시킨 결과에 다시 first_name으로 DISTINCT를 시킬 수 없다.
  3. DISTINCT는 중복 제거를 위해서 SORT를 한다. SORT에 대한 부하가 있다.
    만약 DBMS의 optimizer가 sort가 아닌 hash가 cost가 더 적다고 판단할 경우 Hash를 사용하여 정렬이 안된 결과를 출력한다.
    내 짧은 생각으로는 index가 부여가 안된 칼럼을 이렇게 처리하는 것 같다

* 집계 함수는 Null 값을 무시한다.

집계 함수

  1. SUM
    1. select salary, sum(salary)
      오류 발생 : salary는 107개의 record를 가지고 있고 sum(salary)는 하나의 record이다. 때문에 2차원 테이블로 출력을 할 수 없으므로 오류 발생
    2. 위와 같은 것을 처리하기 위해서 GROUP BY를 사용한다.
  2. COUNT
    1. Null 값을 무시
  3. STDDEV - 표준편차
  4. VARIANCE - 분산
  5. GROUP BY
    1. GROUP BY는 HASH function을 사용한다.
    2. SELECT 문장에서 GROUP BY 절을 사용할 경우에는 SELECT 리스트에 있는 항목 중 집계 함수를 제외하고는 모든 항목이 GROUP BY절에 명시되어야 한다.
      - WHY??
         아마도 다른 Column을 Select 문에 사용한다면 GROUP BY 된 결과와
         수가 다르기 때문에 출력을 할 수 없기 때문일 거라고 생각한다.

    3. SELECT department_id, job_id,
             SUM(SALARY),
             SUM(commission_pct)
      FROM EMPLOYEES
      GROUP BY department_id;
       - 이 경우에는 오류를 발생한다.
         이를 해결하려면 SELECT 문에 job_id를 삭제하거나 GROUP BY를 department_id와 job_id로 그룹을 지면 됨
    4. GROUP BY A, B
      이와 같은 경우는 A가 주 분류 기준이고 B가 부분류 기준이다.
    5. 상수는 그냥 추가할 수 있다.
      예) SELECT 'ORACLE' company, sum(salary)....
  6. HAVING
    1. SELECT department_id, COUNT(*)
      FROM EMPLOYEES
      WHERE department_id IS NOT NULL AND COUNT(*)<=5
      GROUP BY department_id
      ORDER BY department_id;
      위와 같은 query는 오류를 발생한다. WHERE 절은 FROM 절에서 명시한 테이블에서 조건에 맞는 tuple을 골라내는 역할을 한다. 그런데 COUNT 같은 함수는 테이블 전체를 봐야지만 알 수 있는 것이다. 때문에 오류를 발생시킨 것이다. 이를 해결하기 위해서는 HAVING 절을 추가 하면 된다.
      HAVING 절은 GROUP 지어진 결과 set에 대해 조건을 주기 위한 것이다.
    2. SELECT department_id, COUNT(*)
      FROM EMPLOYEES
      WHERE department_id IS NOT NULL
      GROUP BY department_id
      HAVING COUNT(*) <= 5
      ORDER BY department_id;
      이처럼 고치면 된다.
  7. ROLLUP
    1. 그룹핑된 결과에 그룹별 합계 정보를 추가

    2. GROUP BY c.city, b.department_name, a.job_id
      위의 query는 단지 도시와 부서 그리고 직무에 대해서 그룹핑한 결과이다. 이것을 그룹핑의 주 분류 안에서 도시별, 부서별, 지급별 합계를 볼 수 있게 하는 명령어가 ROLLUP이다.
      => GROUP BY ROLLUP(c.city, b.department_name, a.job_id)
  8. CUBE (멋있는 기능 같은 ㅋㅋㅋ 그런데 부하가 없을까??)
    1. 그룹핑된 칼럼의 모든 가능한 조합에 대한 합계 정보를 추가한다.

    2. GROUP BY CUBE(c.city, b.department_name, a.job_id)
      ROLLUP은 주 분류 안에서 도시별, 부서별, 지급별 합계를 볼 수 있게 하지만 CUBE는 주 분류뿐만이 아닌 대분류, 중분류, 소분류까지의 합계도 볼 수 있게 한다.
      만약 도시가 런던인 곳의 분석을 하려고 하면 WHERE 절에 c.ctiy = '런던'만 넣어주면 된다.

SELECT -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY 순으로 기술



사족 - 데이터 베이스 스키마 ERD에서 점선인 relationship은 pk가 관계되는 부분의 pk가 아닌 데이터로 들어가는 것이고 실선인 relationship은 pk가 관계되는 부분의 pk로 들어간 것이다.

728x90

'Computer Science & Engineering > Oracle' 카테고리의 다른 글

[SQL_오라클] 서브쿼리  (0) 2022.06.10
[SQL_오라클] JOIN  (0) 2022.06.10
[SQL_오라클] 1일차 숙제  (0) 2022.06.10
[SQL_오라클] WHERE 절  (0) 2022.06.08
[SQL_오라클] 시작  (0) 2022.06.08

댓글