나만 알 수 없어서 만든 블로그
1.5 DATABASE 서브쿼리 VS 스칼라쿼리 (각각의 장단점 이해) 본문
서브쿼리 VS 스칼라쿼리 (각각의 장단점 이해)
참고링크: https://ttend.tistory.com/619
SQL 기초] 서브쿼리(Sub Query) 개념
서브쿼리(Sub Query)는 SQL 문장의 하부 절에 쿼리문을 사용하는 것이다. 즉, 메인쿼리의 SELECT문 하부의 WHERE절이나 FROM절에서 사용되는 쿼리를 서브쿼리라고 한다. 쿼리 안에 쿼리가 포함된 상태라
ttend.tistory.com
서브쿼리 => SQL 문장의 하부절에 쿼리문을 사용하는 것
SCOTT @ ORACLE > SELECT ename, sal FROM emp
2 WHERE sal >
3 (SELECT sal FROM emp WHERE ename='CLARK');
ENAME SAL
-------------------- ----------
JONES 2975
BLAKE 2850
SCOTT 3000
KING 5000
FORD 3000
서브쿼리 주의사항
- 연산자의 오른쪽에 위치해야한다.
- 괄호로 묶어주어야한다.
서브쿼리의 위치에 따른 명칭
위치 | 명칭 |
SELECT | 스칼라 서브쿼리 |
FROM | 인라인 뷰 |
WHERE | 서브쿼리 |
단일 행 서브쿼리(Single-Row Subquery)
- 서브쿼리의 결과가 1개의 행만 출력
- 단일 행 서브쿼리에서는 단일행 비교연사자인 =, <>, <, > 등의 연산자를 사용 가능
-- =연산자를 사용해서 이름이 smith인 직원과 같은 부서의 직원 조회
SCOTT @ ORACLE > SELECT ename, deptno FROM emp
2 WHERE deptno = (SELECT deptno FROM emp WHERE ename='SMITH');
ENAME DEPTNO
-------------------- ----------
SMITH 20
JONES 20
SCOTT 20
ADAMS 20
FORD 20
-- ">" 연산자를 사용해서 이름이 clark인 직원의 급여보다 많은 직원 조회
SCOTT @ ORACLE > SELECT ename, sal FROM emp WHERE ename='CLARK';
ENAME SAL
-------------------- ----------
CLARK 2450
SCOTT @ ORACLE > SELECT ename, sal FROM emp
2 WHERE sal > (SELECT sal FROM emp WHERE ename='CLARK');
ENAME SAL
-------------------- ----------
JONES 2975
BLAKE 2850
SCOTT 3000
KING 5000
FORD 3000
다중 행 서브쿼리(Multiple-Row Subquery)
서브쿼리의 결과가 여러 건 출력
다중 행 서브쿼리에서 사용할 수 있는 다중행 비교 연산자들 | |
IN | 값은 값을 찾음 =와 같은 역할 서브쿼리의 반환이 1행 이상일 때 그 행들의 값을 반환 |
> ANY | 최솟값을 반환 |
< ALL | 최솟값을 반환 |
< ANY | 최댓값을 반환 |
> ALL | 최댓값을 반환 |
EXIST | 서브쿼리 값이 있을 경우 반환 |
최솟값, 최대값의 의미보다는 등호(<, >)의 위치가 더 중요 | |
> ANY는 이후 뒤 따라 나오는 서브쿼리의 여러 값 중에서 어느 값보다 큰 값을 의미 |
|
< ALL은 뒤의 서브쿼리의 모든 값보다 작은 값을 의미 |
-- job이 president인 사람과 같은 부서에 근무하는 사람을 조회
SCOTT @ ORACLE > SELECT ename, job, deptno FROM emp
2 WHERE deptno
3 IN (SELECT deptno FROM emp WHERE job='PRESIDENT');
ENAME JOB DEPTNO
-------------------- ------------------ ----------
MILLER CLERK 10
KING PRESIDENT 10
CLARK MANAGER 10
최솟값, 최대값의 의미보다는 등호(<, >)의 위치가 더 중요
-- > ANY는 이후 뒤 따라 나오는 서브쿼리의 여러 값 중에서 어느 값보다 큰 값을 의미
-- < ALL은 뒤의 서브쿼리의 모든 값보다 작은 값을 의미
SCOTT @ ORACLE > SELECT ename, sal FROM emp WHERE job='SALESMAN';
ENAME SAL
-------------------- ----------
ALLEN 1600
WARD 1250
MARTIN 1250
TURNER 1500
SCOTT @ ORACLE > SELECT ename, sal FROM emp
2 WHERE sal > ANY(SELECT sal FROM emp WHERE job='SALESMAN');
ENAME SAL
-------------------- ----------
KING 5000
FORD 3000
SCOTT 3000
JONES 2975
BLAKE 2850
CLARK 2450
ALLEN 1600
TURNER 1500
MILLER 1300
9 개의 행이 선택되었습니다.
SCOTT @ ORACLE > SELECT ename, sal FROM emp
2 WHERE sal < ALL(SELECT sal FROM emp WHERE job='SALESMAN');
ENAME SAL
-------------------- ----------
ADAMS 1100
JAMES 950
SMITH 800
다중 컬럼 서브쿼리(Multi-Column Subquery)
- 서브쿼리의 결과가 여러 칼럼을 출력
- 메인쿼리 WHERE절과 서브쿼리에서 반환하는 컬럼의 수가 반드시 같아야만 함
-- 부서별로 가장 작은 급여(sal)를 받는 직원을 조회
SCOTT @ ORACLE > SELECT deptno, ename, sal FROM emp
2 WHERE (deptno, sal) IN
3 (SELECT deptno, MIN(sal) FROM emp GROUP BY deptno)
4 ORDER BY deptno;
DEPTNO ENAME SAL
---------- -------------------- ----------
10 MILLER 1300
20 SMITH 800
30 JAMES 950
스칼라 서브쿼리(Scala Subquery)
- SQL에서 단일값을 스칼라값
- 스칼라 서브쿼리는 SELECT절에 오는 서브쿼리로 결과값으로 1행만 반환
-- 직업이 ‘MANAGER’인 사원의 사원명, 부서명, job을 조회
-- SELECT문 안에 SELECT문이 스칼라 서브쿼리로 사용.
SCOTT @ ORACLE > SELECT ename,
2 (SELECT dname FROM dept d
WHERE d.deptno = e.deptno) dname, job
3 FROM emp e
4 WHERE job ='MANAGER';
ENAME DNAME JOB
-------------------- ---------------------------- ------------------
JONES RESEARCH MANAGER
BLAKE SALES MANAGER
CLARK ACCOUNTING MANAGER
상호연관 서브쿼리(Correlated Subquery)
- 상호관련 서브쿼리라고도 칭함
- 메인쿼리의 값을 서브쿼리에 주고 서브쿼리를 수행한 다음 그 결과를 다시 메인쿼리로 반환해서 수행하는 쿼리
SCOTT @ ORACLE > SELECT ename, sal, deptno FROM emp ORDER BY deptno, sal;
ENAME SAL DEPTNO
-------------------- ---------- ----------
MILLER 1300 10
CLARK 2450 10
KING 5000 10
SMITH 800 20
ADAMS 1100 20
JONES 2975 20
SCOTT 3000 20
FORD 3000 20
JAMES 950 30
MARTIN 1250 30
WARD 1250 30
TURNER 1500 30
ALLEN 1600 30
BLAKE 2850 30
14 개의 행이 선택되었습니다.
-- 부서별 평균 sal
SCOTT @ ORACLE > SELECT deptno, AVG(sal) FROM emp GROUP BY deptno;
DEPTNO AVG(SAL)
---------- ----------
30 1566.66667
20 2175
10 2916.66667
SCOTT @ ORACLE > SELECT ename, deptno, sal
2 FROM emp e1
3 WHERE sal > (SELECT AVG(sal)
4 FROM emp e2
5 WHERE e2.deptno=e1.deptno)
6 ORDER BY deptno;
ENAME DEPTNO SAL
-------------------- ---------- ----------
KING 10 5000
JONES 20 2975
SCOTT 20 3000
FORD 20 3000
ALLEN 30 1600
BLAKE 30 2850
6 개의 행이 선택되었습니다.
-- 1) 메인쿼리에서 부서번호(e1.deptno)를 읽어서 서브쿼리로 전달
-- 2) 서브쿼리는 메인쿼리에서 받은 부서번호로 평균 급여 계산
-- 3) 다시 메인쿼리는 서브쿼리의 평균 급여보다 큰 급여의 직원 출력