DB_SQL_서브쿼리01

BBBeom·2022년 8월 8일

DB

목록 보기
4/18

서브쿼리?

SQL문을 실행하는데 필요한 데이터를 추가로 검색하기위해
SQL문 내부에서 SQL문을 한번더 사용하는데 이때의 SQL문을 의미한다


사원이름이 'JONES'인 사원의 급여 출력은 다음과 같다

SELECT SAL
FROM EMP
WHERE ENAME = 'JONES';

'JONES'의 급여보다 높은 급여를 받는 사원의 정보 출력이라면 어떻게 해야될까?
SELECT *
FROM EMP
WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME = 'JONES');

조건절에 쿼리문이 들어와있다 이때의 쿼리문을 서브쿼리라고 한다


서브쿼리 문법

  1. 연산자와 같은 비교/조회 대상의 오른쪽에 놓이며
    ( )로 묶어서 표현한다
  2. 특별한 경우를 제외하고 서브쿼리안에 ORDER BY 절은 사용이 불가능하다
  3. SELECT절에 명시한 열은 메인쿼리의 비교대상과 같은 자료형과 개수로 지정되어야 한다

단일행 서브쿼리

서브쿼리의 출력값이 1개의 행이면 단일행 서브쿼리라고 한다
단일행 서브쿼리는 단일 행 비교 연산자(=, <, <=, >, >=, <>)와 함께 사용한다

  • EX. EMP테이블의 사원정보 중 사원이름이
    'ALLEN'인 사원의 추가수당(COMM) 보다
    많은 추가수당을 받는 사원정보를 출력
SELECT *
FROM EMP
WHERE COMM > (SELECT COMM FROM EMP WHERE ENAME = 'ALLEN');

  • EX. EMP테이블의 'SCOTT'보다 빨리 입사한 사원들의 목록
SELECT *
FROM EMP
WHERE HIREDATE < (SELECT HIREDATE FROM EMP WHERE ENAME = 'SCOTT');

  • EX. 부서가 20번인 사원중 전체사원의 평균 급여보다 높은 급여를 받는
    사원 정보와 소속 부서정보를 출력 ?
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DEPTNO, D.DNAME, D.LOC
FROM EMP E, DEPT D
WHERE D.DEPTNO = 20 AND E.SAL > (SELECT AVG(SAL) FROM EMP);

JOIN한 상태의 쿼리문안에서 서브쿼리는 JOIN상태인 테이블을
써야하는게 아닌 기본 테이블 형태에서 조건을 달아주면 된다


다중행 서브쿼리

서브쿼리의 결과값이 다중행으로 출력되면
다중행 연산자를 사용해야 연산이 가능해진다
다중행 연산자에는 4가지 종류가 있다

  • 다중행 연산자
    • IN
    • ANY, SOME
    • ALL
    • EXISTS

1. IN 연산자

메인쿼리의 비교조건이 서브쿼리 결과 중에서 하나라도 일치하면 참 (=연산자로 비교한다)

  • EX. 각 부서별 최고 급여와 동일한 급여를 받는 사원 정보 출력
SELECT *
FROM EMP
WHERE SAL IN(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);

GROUP BY DEPTNO 때문에 서브쿼리의 결과가 다중행으로 나온다
(부서번호별 최고급여)

기존의 IN문법과 똑같다고 생각하면 된다
=으로 단일행 연산을 하고 IN으로 다중행연산을 한다
값이 같으면 TRUE 값이 다르면 FALSE인 것이다



2. ANY/SOME 연산자

메인쿼리의 비교조건이 서브쿼리의 검색결과와 하나 이상 일치하면 참

  • ANY 연산자
SELECT *
FROM EMP
WHERE SAL = ANY(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
  • SOME 연산자
SELECT *
FROM EMP
WHERE SAL = SOME(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
  • ANY와 SOME의 결과값은 동일하게 나온다
    보통 ANY로 사용한다

IN연산자의 결과값과 동일하지만 차이점은
ANY연산자는 ANY앞에 (=, <, <=, >, >=, <>) 연산자를 사용한다
IN은 사용하지 못한다 그래서 =으로 비교할 경우에는 보통 IN연산자를 쓰고
그외 비교를 할때는 ANY를 사용한다



3. ALL 연산자

메인쿼리의 비교조건이 서브쿼리의 검색결과와 모든값이 일치하면 참
검색한 값을 AND연산해서 모두 참이면 참이 된다
(각 데이터별이 아닌 서브쿼리 값의 범위로 비교한다고 생각)

  • EX. 30번 부서의 사원들의 급여보다 많은 급여를 받는 사원정보 출력
SELECT *
FROM EMP
WHERE SAL > ALL(
SELECT SAL
FROM EMP
WHERE DEPTNO = 30);

/*10번 부서의 속한 모든 사원들보다 일찍 입사한 사원 정보를 출력*/

SELECT *
FROM EMP
WHERE HIREDATE < ALL(
SELECT HIREDATE FROM EMP WHERE DEPTNO = 10);


4. EXISTS 연산자

메인쿼리의 데이터가 서브쿼리의 검색결과와 하나라도 일치하면
조건식이 모두 TRUE
아무것도 일치하지 않으면 FALSE

SELECT * FROM EMP
WHERE EXISTS(SELECT SAL FROM EMP WHERE DEPTNO = 50)

서브쿼리의 값이 메인쿼리의 데이터값에 한개이상 존재하므로 TRUE
EMP테이블의 모든값들을 정상적으로 출력한다

메인쿼리의 데이터가 서브쿼리의 데이터에도 있는지 없는지 확인하는 정도로만 쓰임 (많이 쓰이진 않는다)


단일행, 다중행에 따른 쿼리문의 문법과
IN, ANY, ALL의 사용법은 확실하게 알아둘것

profile
BackEnd_BasketBall_Beom

0개의 댓글