카테고리 없음

[Oracle] 서브 쿼리

뽀글뽀글 개발자 2023. 4. 7. 13:47

서브 쿼리란?

쿼리에 필요한 내용을 조회하는 쿼리로 SQL문 내부에서 SELECT 문을 사용하는 것을 의미한다.

# EMP테이블에서 'JONES' 보다 급여가 높은 사원의 이름을 불러오는 쿼리
SELECT ENAME
FROM EMP
WHERE SAL > ( SELECT SAL
		FROM EMP
               WHERE ENAME = 'JONES');

 

다중열 서브쿼리

비교할 열이 여러 개인 경우 아래와 같이 괄호로 컬럼의 순서를 맞추면 된다.

SELECT *
  FROM EMP
 WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL)
                           FROM EMP
                       GROUP BY DEPTNO);

 

SELECT 절 서브쿼리

"스칼라 서브쿼리"라고도 부른다

SELECT EMPNO, ENAME, JOB, SAL,
		(SELECT GRADE
        	  FROM SALGRADE
            	 WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE
FROM EMP E;

 

FROM 절 서브쿼리

테이블을 1개 행을 전부 가져와서 별칭을 붙여주는 방식으로 가독성이 떨어지는 문제가 있다.

이를 해결하기 위해 WITH 절을 사용한다.

SELECT E10.EMPNO, E10.ENAME, E10.DEPTNO, D.DNAME, D.LOC
FROM (SELECT * FROM EMP WHERE DEPTNO = 10) E10, 
     (SELECT * FROM DEPT) D
WHERE E10.DEPTNO = D.DEPTNO;

 

WITH 절 서브쿼리

FROM 절 서브쿼리의 결과와 별칭 정의를 핵심 쿼리와 분리시켜 가독성을 향상시킨다.

WITH
E10 AS (SELECT * FROM EMP WHERE DEPTNO = 10), 
D   AS (SELECT * FROM DEPT)
SELECT E10.EMPNO, E10.ENAME, E10.DEPTNO, D.NAME, D.LOC
  FROM E10, D
 WHERE E10.DEPTNO = D.DEPTNO;

 

서브쿼리와 함께 자주 사용되는 연산자

IN

여러 개의 ROW에 해당 데이터가 포함되는지 확인 후 TRUE, FALSE를 반환한다.

서브쿼리의 결과가 여러 개인 다중행 서브 쿼리에 자주 사용된다.

# 부서별 최고 급여 중 동일한 급여를 받는 사원 조회
SELECT * 
  FROM EMP
  WHERE SAL IN (SELECT MAX(SAL)
         	   FROM EMP
                   GROUP BY DEPTNO);

 

ANY,  SOME  (동일함)

# 부서별 최고 급여 중 가장 낮은 급여보다 낮은 급여를 받는 사원 조회
SELECT * 
  FROM EMP
  WHERE SAL < ANY (SELECT MAX(SAL)
         	   FROM EMP
                   GROUP BY DEPTNO);

모든 데이터에 대해 추가적인 연산을 적용할 때 사용되며, 서브쿼리의 값들 중 하나라도 일치하면  TRUE를 반환한다.

SAL = ANY가 되면, IN과 동일하다.

 

ALL

모든 결과가 조건에 만족할 경우  TRUE를 반환한다.

# 부서별 최고 급여 중 가장 낮은 급여보다 낮은 급여를 받는 사원 조회
SELECT * 
  FROM EMP
  WHERE SAL < ALL (SELECT MAX(SAL)
         	   FROM EMP
                   GROUP BY DEPTNO);

 

EXISTS

서브쿼리의 결과가 1개라도 존재하면 TRUE를 반환한다. 

SELECT * 
  FROM EMP
  WHERE EXISTS (SELECT MAX(SAL)
         	   FROM EMP
                   GROUP BY DEPTNO);