<목차>
ㅇ 인라인 뷰 (셀렉트 문장의 끝판왕)
ㅇ rownum
ㅇ TOP-N분석
CF. 엄청 어려워ㅜㅜ 셀렉트 문장의 많은 경험이 있는 사람들이 사용할 수 있는 정도로)
ㅇ 인라인 뷰 예제
SELECT a.last_name, a.salary, a.department_id, b.maxsal FROM employees a, (SELECT department_id, MAX(salary) maxsal FROM employees GROUP BY department_id) b WHERE a.department_id = b.department_id AND a.salary < b.maxsal
(내생각. 결국은 각 부서 최대급여 받는 사원들 제외하고 모두 찾는 건가?!)
SELECT rownum, last_name, salary FROM employees WHERE rownum > 4 수보다 크다는 조건 주면 결과 안 나와 SQL>/ no rows selected
- 로우넘버는 행이 출력돼야지만 리턴해줌
ㅇ 실험 : 급여 조금 받는 순서대로 3명 찾으려고 시도
SELECT rownum, last_name, salary FROM employees WHERE rownum < 4 ORDER BY salary
- 결과
ROWNUM LAST_NAME SALARY 2 Kochhar 17000 3 De Haan 17000 1 King 24000
SELECT rownum, last_name, salary FROM (SELECT last_name, salary FROM employees ORDER BY salary) WHERE rownum < 4
ㅇ 꼭 기억해야 할 사항
Q. 처음부터 테이블 정렬되어 있으면 편하지 않을까?
ㅇ 실습1 : 50번 부서에 근무하는 사원 중 연봉을 많이 받는 상위 3명의 이름과 연봉을 구하시오.
- 오답1 : 서브쿼리에서 '급여'로 정렬한 뒤 본쿼리에서 '연봉'을 출력해주는 방법
SELECT rownum, last_name, salary*12 FROM (SELECT last_name, salary FROM employees ORDER BY salary DESC) WHERE rownum < 4
- 이렇게 해도 결과는 똑같지만, 문제에서는 '연봉을 많이 받는 순서대로' 상위 3명을 구하라고 했으니까 문제에 맞게 '연봉'으로 정렬하자.
- 오답2 : 그래서 연봉인 salary*12로 정렬하려 시도하겠지?
=> 이러면 오류 나SELECT rownum, last_name, salary*12 FROM (SELECT last_name, salary*12 FROM employees ORDER BY salary*12 DESC) WHERE rownum < 4
- 지금 FROM절에 있는 테이블은 임플로이스 테이블이 아니라 서브쿼리로 만든 인라인 뷰잖아.
- 근데 본쿼리에서 'salary*12'는 임플로이스테이블에서 나온 salary에 산술연산자 *12를 하라는 거야
- FROM절의 인라인 뷰에는 salary 컬럼 없어!
정답
SELECT rownum, last_name, annsal FROM (SELECT last_name, salary*12 annsal FROM employees ORDER BY annsal DESC) WHERE rownum < 4
ROWNUM LAST_NAME ANNSAL 1 Davies 480000 2 Rajs 360000 3 King 288000 - ORDER BY 절은 맨 마지막 실행이니 알리아스 가능
ㅇ 실습2 : 평균 급여가 적은 하위 3개 부서의 이름과 평균 급여를 출력하시오.
내 오답 1 : 부서 이름을 적어야 하는 데 부서 아이디 사용함.. 어쩐지 넘 빨리 끝나더라;;ㅋㅋㅋ
SELECT rownum, department_id, avg_sal FROM (SELECT department_id, AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY AVG(salary)) WHERE rownum < 4
- CF) 내가 자주 하는 실수 : 오더바이절에 salary 만 넣음. 우리가 원하는 정렬은 평균들의 정렬이니까 AVG(salary)를 정렬해야지!!!
내 답 : 결과는 같지만 조인이 본쿼리에 사용되어 성능 떨어져
SELECT rownum, d.department_name, a.avg_sal FROM departments d, (SELECT department_id, AVG(salary) avg_sal FROM employees GROUP BY department_id ORDER BY avg_sal) a WHERE d.department_id = a.department_id AND rownum < 4
- 쌤 답은 쿼리를 한 번에 돌리게끔
- 셀렉트 데이터 셋이라고 이야기 해
- 쿼리가 데이터 셋을 만든거야
- 내가 한 건 한 번 더 수행해야 하는 쿼리
정답
SELECT department_name, avg_sal FROM (SELECT d.department_name, AVG(e.salary) avg_sal FROM departments d, employees e WHERE d.department_id = e.department_id GROUP BY d.department_id ORDER BY AVG(e.salary) ASC) WHERE rownum < 4
(만드는 순서)
서브쿼리
SELECT d.department_name, AVG(e.salary) FROM departments d, employees e WHERE d.department_id = e.department_id GROUP BY d.department_id ORDER BY AVG(e.salary) ASC
CF) 내가 계속 헷갈려 하는 부분