5월 24일 월요일 (10일차) - 그룹바이절,해빙절ㅇ

@_@·2021년 5월 24일
0

Database

목록 보기
19/28

<목차>
ㅇ GROUP BY
ㅇ HAVING




ㅇ 실험) 부서별 급여의 총합을 구하세요. 즉, 결과를 각 부서별로 보고 싶어.

SELECT department_id, sum(salary)
FROM employees
ERROR at line 1:
ORA-00937: not a single-group group function

부서별 이니까 department_id를 살펴보려고 시도하겠지?!
셀렉트 절의 department_id 컬럼 때문에 에러가 나

  • 그룹 함수는 그룹 당 하나의 결과인데, d_id는 그룹화 되어있지 않고 행으로 되어 있어서 에러가 발생했어.
  • 부서별로 sum 하려면 10번끼리, 20번끼리 모아 둬야 해
    => 즉, 그룹화를 시켜주자.



ㅇ GROUP BY 절

SELECT (그룹화해서보여주고싶은)컬럼, 그룹함수(함수실행할컬럼)
FROM 컬럼을 소유한 테이블
WHERE
GROUP BY 그룹화 할 열을 지정
ORDER BY
  • 그룹화가 되지 않은 컬럼들을 그룹화 해줌
  • 셀렉트 리스트절에서 그룹함수가 사용되지 않은 컬럼들은 반드시 그룹바이 절을 이용해서 그룹화 작업을 해 줘야 해 (공식처럼 알아둬)
  • WHERE절과 ORDER BY절 사이에만 위치
  • 그룹화 할 열은 되도록 SELECT list 절에 명시해주기
    • SELECT list 절에 표기하지 않아도 그룹화가 실행되기는 하지만 무슨 기준으로 결과가 나온 건지 모르니까 될 수 있으면 적어둬 (WHERE절, ORDER BY절이 그러했듯이)

Q. 질문 : 디스팅트로 그룹화하면 안 되나?

  • 디스팅트, 오더바이절도 그룹화를 실행하긴 하지만 차이가 있어
  • 내부적으로 그룹화 작업하는 것만 같을 뿐 그 뒤는 달라. 목적이 달라
  • 디스팅트 : 똑같은 애들끼리 그룹을 모아서 이 중에 하나를 도출하는 작업
  • 오더바이절 : 똑같은 애들끼리 모아서 출력하기 위한 거고
  • 그룹바이절 : 그룹화해서 '인수'로 사용하는 거야

ㅇ 여러 열에 GROUP BY절 사용

  • 첫 번째 컬럼을 기준으로 그룹화 -> 그 안에서 두 번째가 그룹화 -> 그 다음 그룹함수 적용
  • 셀렉트 절이 순서의 기준이야. (그룹바이 절에 적는 순서는 상관없어)

부서별, 그 안에서 직업별 급여

SELECT department_id dept_id, job_id, sum(salary)
FROM employees
GROUP BY department_id, job_id
ORDER BY department_id



ㅇ 실험) 평균 급여가 8000보다 큰 부서를 출력하여라.

조건이 생겼으니까 WHERE절에 넣었더니 오류 나

SELECT department_id, AVG(salary)
FROM employees
WHERE AVG(salary)>8000
GROUP BY department_id
SQL> /
ERROR at line 3:
ORA-00934: group function is not allowed here
  • 웨어절을 사용하여 그룹을 제한할 수 없다.
    (나중에 나오겠지만 그룹함수를 웨어절에 사용하고 싶으면 서브쿼리 이용)

ㅇ HAVING 절

  • 그룹에 대한 조건을 주고자 할 때
  • WHERE절에 그룹함수를 사용할 수 없어
    • WHERE절이 행을 먼저 필터링을 하기 때문에
  • 그룹함수에 대한 값은 변화가 일어나는 값이야 (테이블에 존재하는 값이 아니라)
  • 그래서 WHERE가 아니라 HAVING을 써
  • GROUP BY절과 HAVING절은 순서 바뀌어도 돼
    • 웨어절과 오더바이절 사이에만 위치하면 돼
    • 가독성 측면에서 그룹바이가 먼저 나열되는 걸 권장

ㅇ 실습1 : 부서별 최대급여 찾되(그룹바이), 급여가 10000보다 큰 부서만 도출(해빙)

SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id
HAVING MAX(salary)>10000

ㅇ 실습 : 주어진 코드가 무엇을 의미하는가?

  • 웨어절이 먼저 실행되므로 알이피가 안 들어가는 직업별 총합을 구하되, 총합이 13000보다 큰 직업들만 출력하세요.
SELECT job_id, SUM(salary), PAYROLL
FROM employees
WHERE job_id NOT LIKE '%REP%'
GROUP BY job_id
HAVING SUM(salary) > 13000
ORDER BY SUM(salary)

ㅇ 셀렉트 문장의 조건절 2가지 비교 : 웨어절, 해빙절

  • 웨어절 : 테이블에 있는 데이터를 기준으로 조건을 부여
    • 행을 제한하는 절 / 행에 조건을 주는
    • 컬럼만 사용 / 컬럼+연산자+값
  • 해빙 : 그룹함수에 의해 도출이 된 결과들을 제어
    • 그룹을 제한하는 절 / 그룹에 조건을 주는
    • 그룹함수를 사용 / 그룹함수+연산자+값
  • 웨어절에 그룹함수를 쓰면 안 돼 : (그룹바이절보다) 웨어절이 먼저 실행되기 때문에
  • 해빙절에 일반 조건 웬만하면 쓰지 말자
    • 처리는 이루어지지만
    • 다만, 성능이 떨어져 : 셀렉트절에 의해 변경된 값이 떨어지고 나서 해빙절이 다시 역산으로 수행되기 때문에


(내생각)

Q. 최종 실행 순서는?
프럼절 -> 웨어절 -> 그룹바이절&해빙절 -> 셀렉트절 -> 오더바이절

Q. 그래서 알리아스는?

  • 프럼절에 '테이블' 알리아스 주면, 다른 절에서 다 접두어로 사용가능
  • 셀렉트절에 '컬럼'에 알리아스 주면, 오더바이절에만 사용가능


실행 순서 맞음 (참고) https://myjamong.tistory.com/172



profile
STEP BY STEP

0개의 댓글