티스토리 뷰

SQL

[Oracle SQL] 서브쿼리(subquery)

Alledy 2019. 5. 20. 17:03

서브쿼리(subquery)

  • def: sql문 실행에 필요한 데이터를 추가로 조회하기 안에 sql문 내부에 사용하는 select문

  • 예시

    -- 마치 변수를 사용하는 것 같다
    SELECT * FROM EMP 
    WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME = 'JONES')
    
    -- 함수를 사용한 단일행 서브쿼리문
    SELECT E.EMPNO, E.ENAME, E.SAL, D.DEPTNO FROM EMP E, DEPT D
    WHERE E.DEPTNO = D.DEPTNO -- join조건문
    AND E.DEPTNO = 20
    AND E.SAL > (SELECT AVG(SAL) FROM EMP); 
    

     

다중행 서브쿼리

  • 다중행 서브쿼리(multi-row subquery)는 실행 결과 값이 여러 개로 나오는 서브쿼리이다.

 

  • IN 연산자

    -- 원래 in 연산자, 부서번호가 20 또는 30인 사원 정보 출력
    SELECT * FROM EMP WHERE DEPTNO IN(20,30); 
    
    -- 각 부서별 최고 급여를 받는 사원 정보 출력 
    SELECT * FROM EMP WHERE SAL IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO)
    

     

  • ANY, SOME 연산자

    서브쿼리가 반환한 여러 결과 값 중 메인쿼리와 조건식을 사용한 결과가 하나라도 true이면 메인쿼리 조건식을 true로 반환해주는 연산자.

    -- 등가연산자(=)와 함께 사용하는 경우 IN과 같은 기능 수행
    SELECT * FROM EMP 
    WHERE SAL = ANY (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
    
    -- 대소비교연산자 사용. 부서번호 30의 sal 최대값보다 작은 sal을 받는 사원 정보를 출력
    SELECT * FROM EMP
    WHERE SAL < ANY(SELECT SAL FROM EMP WHERE DEPTNO = 30);
    

     

  • ALL 연산자

    ANY와 다르게 서브쿼리의 모든 결과가 조건식에 맞아떨어져야 메인커리의 조건식이 true가 되는 연산자.

    -- 부서번호가 30인 sal의 최솟값보다 작은 경우
    SELECT * FROM EMP 
    WHERE SAL < ALL (SELECT SAL FROM EMP WHERE DEPTNO = 30); 
    

     

  • EXISTS 연산자

    서브쿼리에 결과 값이 하나 이상 존재하면 조건식이 모두 true, 존재하지 않으면 false가 되는 연산자.

    -- 존재하지 않는 경우 아무 것도 출력하지 않는다.
    SELECT * FROM EMP 
    WHERE EXISTS (SELECT DNAME FROM DEPT WHERE DEPTNO = 50); 
    
    -- 서브쿼리 결과값이 존재하므로 emp 모든 행을 출력한다. 
    SELECT * FROM EMP
    WHERE EXISTS (SELECT DNAME FROM DEPT WHERE DEPTNO = 10); 
    

     

그 외 서브쿼리

  • 비교할 열이 여러 개인 다중열 서브쿼리

    메인쿼리에 비교할 열을 괄호로 묶어 명시하고 서브쿼리에서는 괄호로 묶은 데이터와 같은 자료형 데이터를 명시한다.

    -- 비교하는 열이 sal과 deptno 2개
    SELECT * FROM EMP 
    WHERE (DEPTNO, SAL) IN (SELECT DEPTNO, MAX(SAL) FROM EMP GROUP BY DEPTNO) 
    

     

  • FROM 절에서 사용하는 서브쿼리

    -- 인라인뷰(inline view). 일부 데이터를 먼저 추출한 다음 별칭을 붙여 사용
    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;
    

    from절에 너무 많은 서브쿼리를 지정하면 가독성이 떨어져 with절을 사용하기도 한다.

     

  • SELECT 절에 사용하는 서브쿼리

    -- 스칼라 서브쿼리(scalar subquery)
    SELECT EMPNO, ENAME, JOB, SAL, 
    (SELECT GRADE FROM SALGRADE WHERE E.SAL BETWEEN LOSAL AND HISAL) AS SALGRADE,
    DEPTNO,
    (SELECT DNAME FROM DEPT WHERE E.DEPTNO = DEPT.DEPTNO) AS DNAME 
    FROM EMP E;
    

     

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함