DB-Oracle

Oracle SQL - SUBQUERY, SET Operation

jmeen 2021. 8. 5. 14:21
728x90

Oracle SQL - SUBQUERY, SET Operation

Subquery

하나의 SQL 질의문 속에 다른 SQL 질의문이 포함되어 있는 형태
예) 'SCOTT' 보다 급여가 많은 사람은?
급여가 많은 사람의 이름?

SELECT ename FROM emp WHERE sal > ???


'SCOTT'의 급여는?

SELECT sal FROM emp WHERE ename='SCOTT'
SELECT ename FROM emp
	WHERE sal > ( SELECT sal FROM emp
			WHERE ename = ‘SCOTT’ )

[연습] hr.employees
'Den' 보다 급여를 많이 받는 사원의 이름과 급여는?

Single-Row Subquery

Subquery의 결과가 한 ROW인 경우
  - Single-Row Operator를 사용해야 함: =, >, >=, <, <=, <>

SELECT ename, sal, deptno FROM emp
	WHERE ename = (SELECT MIN(ename) FROM emp);

SELECT ename, sal FROM emp
	WHERE sal < (SELECT AVG(sal)FROM emp);

SELECT ename, deptno FROM emp 
	WHERE deptno = (SELECT deptno FROM dept
			WHERE dname = ‘SALES’);

 

Multi-Row Subquery

 - Subquery의 결과가 둘 이상의 Row 
- Multi-Row에 대한 연산을 사용해야 함: ANY, ALL, IN, EXIST …

SELECT ename, sal, deptno
FROM emp
WHERE ename = (SELECT MIN(ename) FROM emp GROUP BY deptno);       -- X = 사용 불가
SELECT ename, sal, deptno
FROM emp
WHERE ename IN (SELECT MIN(ename) FROM emp GROUP BY deptno);

SELECT ename, sal, deptno
FROM emp
WHERE ename = ANY (SELECT MIN(ename) FROM emp GROUP BY deptno);

- ANY는 OR과 비슷, ALL은 AND와 비슷

 

Correlated Query

Outer Query와 Inner Query가 서로 연관되어 있음
 - 해석 방법
 - Outer query의 한 Row를 얻는다
 - 해당 Row를 가지고 Inner Query를 수행한다
 - 수행 결과를 이용, Outer query의 WHERE 절을 evaluate
 - 결과가 참이면 해당 Row를 결과에 포함시킨다

SELECT ename, sal, deptno FROM emp outer
WHERE sal > (SELECT AVG(sal) FROM emp
				WHERE deptno = outer.deptno);

각 부서별로 최고급여를 받는 사원을 출력하시요

SELECT deptno, empno, ename, sal FROM emp
WHERE (deptno,sal) IN (SELECT deptno, max(sal) FROM emp
					GROUP BY deptno);
SELECT e.deptno, e.empno, e.ename, e.sal
	FROM emp e,(SELECT s.deptno, max(s.sal) msal
			FROM emp s GROUP BY deptno) m
			WHERE e.deptno = m.deptno AND e.sal = m.msal;
SELECT deptno, empno, ename, sal FROM emp e
WHERE e.sal = (SELECT max(sal) FROM emp
			WHERE deptno = e.deptno);

Top-K Query (Oracle)

 

  - ROWNUM : 질의의 결과에 가상으로 부여되는 Oracle의 Pseudo Column
  - Top-K Query: 조건을 만족하는 상위 k개의 결과를 빨리 얻기
     - 81년도에 입사한 사람 중 급여가 가장 많은 3명은 누구인가?

SELECT rownum, ename, sal
FROM (SELECT * FROM emp
		WHERE hiredate like '81%'
		ORDER BY sal DESC)
WHERE rownum < 4;

집합(SET) Operator

  - 두 집합의 결과를 가지고 집합 연산을 수행
  -  UNION, UNION ALL, INTERSECT, MINUS

SELECT ename FROM emp
UNION
SELECT dname FROM dept;

 

RANK 관련 함수

 

SELECT sal, ename,
RANK() OVER (ORDER BY sal DESC) AS rank,
DENSE_RANK() OVER (ORDER BY sal DESC) AS dense_rank,
ROW_NUMBER() OVER (ORDER BY sal DESC) AS row_number,
rownum AS "rownum"
FROM emp;

  - RANK : 중복순위 다음은 해당 개수만큼 건너뛰고 다음 순위 반환
  - DENSE_RANK : 중복순위와 상관 없이 다음 순위를 반환
  - ROW_NUMBER : 중복을 같은 순위로 두지 않고 무조건 순서대로 반환

 

Hierarchical Query (Oracle)

  - 트리 형태 구조를 추출하기 위한 질의
  - START WITH (ROOT 조건), CONNECT BY PROIR (연결조건)
  - LEVEL : 트리의 레벨을 나타내는 Pseudo Column

SELECT level, ename
FROM emp
START WITH mgr IS NULL
CONNECT BY PRIOR empno = mgr
ORDER BY level;