[DB_SQL활용] 서브쿼리

예지성준·2024년 5월 13일

DB

목록 보기
10/19
post-thumbnail

SQL문 속 또 다른 SQL문, 서브 쿼리

  • SQL문 내부에 사용하는 SELECT문을 의미

서브 쿼리

SELECT 서브쿼리(1)FROM 서브쿼리(2)WHERE 서브쿼리(3)

(1) 스칼라 서브쿼리

  • 스칼라: 단일값

(2) 인라인 뷰: 가상의 테이블

(3) 상관 부속 질의

SELECT 조회할 열
	FROM 조회할 테이블
WHERE 조건식 ( SELECT 조회할 열 FROM 조회할 테이블 WHERE 조건식 )

-- 서브쿼리로 JONES의 급여보다 높은 급여를 받는 사원 정보 출력
SELECT * FROM EMP
WHERE SAL > (SELECT SAL FROM EMP WHERE ENAME = 'JONES');

1. 특징

1) 서브 쿼리는 연산자와 같은 비교 또는 조회 대상의 오른쪽에 놓이며 괄호( )로 묶어서 사용합니다.

2) 특수한 몇몇 경우를 제외한 대부분의 서브쿼리에서는ORDER BY 절을 사용할 수 없습니다.

3) 서브쿼리의 SELECT절에 명시한 열은 메인쿼리의 비교 대상과 같은 자료형과 같은 개수로 지정해야 합니다. 즉 메인쿼리의 비교 대상 데이터가 하나라면 서브쿼리의 SELECT절 역시 같은 자료형인 열을 하나 지정해야 합니다.

4) 서브쿼리에 있는 SELECT문의 결과 행 수는 함께 사용하는 메인쿼리의 연산자 종류와 호환 가능해야 합니다.

예를 들어 메인쿼리에 사용한 연산자가 단 하나의 데이터로만 연산이 가능한 연산자라면 서브쿼리의 결과 행 수는 반드시 하나여야 합니다.

실행 결과가 하나인 단일행 서브 쿼리

  1. 단일행 서브 쿼리(single-row subquery)는 실행 결과가 단 하나의 행으로 나오는 서브쿼리를 뜻합니다.

  2. 서브쿼리에서 출력되는 결과가 하나이므로 메인쿼리와 서브쿼리 결과는 다음과 같이 단일행 연산자를 사용하여 비교

ex) 30번 부서의 최소 급여보다 적게 받는 직원 목록

🔽

  1. 단일행 서브쿼리와 날짜형 데이터
SELECT * FROM EMP
WHERE HIREDATE < (SELECT HIREDATE FROM EMP WHERE ENAME = 'SCOTT');
  1. 단일행 서브쿼리와 함수
SELECT E.EMPNO, E.ENAME, E.JOB, E.SAL, D.DEPTNO, D.DNAME, D.LOC 
FROM EMP E, DEPT D
WHERE E.DEPTNO = D.DEPTNO 
	AND E.DEPTNO = 20
	AND E.SAL > (SELECT AVG(SAL) FROM EMP);

실행 결과가 여러 개인 다중행 서브 쿼리

  1. 다중행 서브쿼리(multiple-row subquery)는 실행 결과 행이 여러 개로 나오는 서브쿼리를 가리킵니다.

  2. 단일행 서브쿼리와 달리 서브쿼리 결과가 여러 개이므로 단일행 연산자는 사용할 수 없고 다중행 연산자를 사용해야 메인쿼리와 비교할 수 있습니다.

  1. IN 연산자
  • 부서별 최대 급여 직원 목록
-- 부서별 최대 급여 직원 목록
SELECT * FROM EMP 
WHERE SAL IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);

-- 부서별 최대 급여가 아닌 직원 목록
SELECT * FROM EMP 
WHERE SAL NOT IN (SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
  1. ANY, SOME 연산자
  • 쿼리 결과 값이 하나라도 참이면 참
#ANY
-- 부서별 최대 급여 직원 목록
SELECT * FROM EMP
WHERE SAL = ANY(SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO);
-- SELECT MAX(SAL) FROM EMP GROUP BY DEPTNO 여기서 나온 결과중 어떤값 중 하나라도 SAL과 같으면 참

ex) 30번 부서의 최대 급여보다 적게 받는 직원 목록

ex) 30번 부서의 최소 급여보다 더 많이 받는 직원 목록

ex) 30번 부서의 최대 급여보다 더 많이 받는 직원

  1. ALL 연산자
  • 쿼리 결과 값이 모두 참이여야 참

ex) 30번 부서의 최대 급여보다 많이 받는 직원 목록

SELECT SAL FROM EMP WHERE DEPTNO=30 ORDER BY DEPTNO DESC;
--결과
SAL > 2850
SAL > 1600
SAL > 1500
SAL > 1250
SAL > 950
이 모두 참이여야 참이므로 가장 큰 값 2850보다 커야 참이된다.
  1. EXISTS 연산자
  • 서브 쿼리의 결과 레코드가 있으면 참, 없으면 거짓 (조회가 되면 참)

ex) 30번 부서가 부서 테이블에 존재하면 직원목록 출력

참이 아닐경우🔽

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

  1. 서브쿼리의 SELECT절에 비교할 데이터를 여러 개 지정하는 방식

  2. 다중열 서브쿼리 사용하기

FROM절에 사용하는 서브쿼리와 WITH절

  1. 인라인 뷰(inline view)
  • 가상 테이블, 서브 쿼리 결과를 가지고 가상 테이블 생성텍스트

✔인라인 뷰의 단점: FROM절의 쿼리가 너무 길어진다.

  1. WITH절 사용하기 - 오라클 전용 쿼리
    FROM 절이 길어질때 WITH과 별칭 사용
WITH
E AS (SELECT EMPNO, ENAME, JOB, SAL, DEPTNO
		FROM EMP WHERE DEPTNO IN (10,20)),
D AS (SELECT * FROM DEPT)
SELECT E.EMPNO, E.ENAME, D.DNAME
FROM E,D
WHERE E.DEPTNO = D.DEPTNO AND E.SAL >= 2000;
  1. 상호 연관 서브쿼리
  • 메인 쿼리의 결과 데이터를 서브 쿼리에서 사용

SELECT 절에 사용하는 서브쿼리

  1. 스칼라 서브쿼리(scalar subquery)
    스칼라: 단일값 - 단일행 서브쿼리

  2. SLECT절에 서브쿼리 사용하기

SELECT EMPNO, ENAME,
(SELECT DNAME FROM DEPT D WHERE D.DEPTNO = E.DEPTNO) DNAME
FROM EMP E;
-- 각 레코드마다 각각 실행되기 때문에 좋은코드가 아니다 성능 xx
  1. SELECT 절에 명시하는 서브쿼리는 반드시 하나의 결과만 반환하도록 작성

-> 2개 이상의 행이 리턴됨 오류

profile
꽁꽁 얼어붙은 한강 위로 😺

0개의 댓글