728x90
반응형
Sub Query

 

- 서브쿼리는 SQL 문 안에 포함된 또 다른 SQL 문을 의미

- SELECT 문 안에 다시 SELECT 문이 기술된 형태의 쿼리

- 서브 쿼리의 용도는 알려지지 않은 기준을 위한 검색을 위해 사용

- 메인쿼리와 서브쿼리 관계는 주종 관계로서, 서브쿼리에 사용되는 컬럼 정보는 메인쿼리의 컬럼 정보를

사용할 수 있으나 역으로는 성립하지 않는다.

- 상위 SELECT 문 안에 하위 SELECT 문이 포함된 형태라 중첩된(nested) 쿼리라고도 부름

- 단일 SELECT 문 사용만으로는 복잡한 조건식을 만들 때 사용

- 다른 테이블에서 데이터 값을 조회한 후 조건으로 사용할 때 사용

 

> 서브 쿼리 종류 (데이터 형태 기준)

  • 단일 행 서브 쿼리(Single Row) - 중첩 서브쿼리(Nested SubQuery)
    : 하나의 행을 검색하는 서브 질의 / 결과가 항상 1건 이하인 서브쿼리
    : 단일 행 비교 연산자 <, >, = 가 사용
  • 다중 행 서브 쿼리(Multiple Row) - 중첩 서브쿼리(Nested SubQuery)
    : 하나 이상을 검색하는 서브 질의 / 실행 결과가 여러 건인 서브 쿼리
    : 다중 행 비교 연산자 사용 IN, ALL, ANY, EXIST 가 사용
  • 다중 열 서브 쿼리(Multiple Column)
    : 하나 이상을 검색하는 서브 질의 / 결과가 여러 컬럼으로 반환되는 서브 쿼리
    : 메인 쿼리의 조건절에 여러 컬럼을 동시에 비교할 때, 서브 쿼리와 메인 쿼리에서 비교하는 컬럼 개수와 위치가 동일

> 서브 쿼리 종류 (위치 기준)

  • FROM 절 서브쿼리
    - 서브 쿼리가 FROM 절 안에 들어있는 형태
    - 인라인 뷰(Inline Views)라고 불림
    - 뷰(View)처럼 결과가 동적으로 생성된 테이블 형태로 사용할 수 있음
  • WHERE 절 서브쿼리
    - 서브쿼리가 WHERE 절 안에 들어 있는 형태
    - 중첩 (Nested Sub-Query) 라고도 불림

Detail

 

- 단일 행 서브 쿼리

  • : 서브쿼리 SELECT 문에서 단일 행 결과를 메인 쿼리에 전달
  • : WHERE 절에 사용되는 열의 개수와 데이터 타입 일치 필요
  • : 단일 행 연산자 사용: >, <, =, !=
SELECT *
FROM employees
WHERE phone_number = (SELECT phone_number
                      FROM employees
                      WHERE employee_id = 100);
SELECT *
FROM employees
WHERE hire_date = (SELECT hire_date
                   FROM employees
                   WHERE email = 'SKING');
SELECT *
FROM employees
WHERE hire_date < (SELECT hire_date
                   FROM employees
                   WHERE email = 'SKING');
SELECT *
FROM employees
WHERE hire_date >= (SELECT hire_date
                    FROM employees
                    WHERE hire_date = '06/01/03');

 

- 다중 행 서브 쿼리

  • 서브 쿼리 SELECT 문에서 다중 행 결과를 메인 쿼리에 전달
  • 단일 행 연산자는 사용할 수 없고, 다중 행 연산자만 사용 가능
다중 행 연산자 설명
IN 서브 쿼리 결과 중 같은 값이 포함되어 있으면 TRUE IN(100, 101)
NOT IN 서브 쿼리 결과 중 같은 값이 포함되어 있지 않으면 TRUE NOT IN(100, 101)
EXISTS 서브 쿼리의 결과가 존재하면 TRUE EXISTS(100)
ANY(SOME) 조건식을 하나라도 만족하면 TRUE (OR와 비슷) ANY(100, 101)
ALL 조건식을 모두 만족하면 TRUE (AND와 비슷) ALL(100, 101)

 

* IN / NOT IN 연산자

SELECT *
FROM employees
WHERE salary IN (SELECT MAX(salary)
                 FROM employees
                 GROUP BY department_id);
SELECT *
FROM employees
WHERE salary NOT IN (SELECT MAX(salary)
                     FROM employees
                     GROUP BY department_id);

 

* EXISTS 연산자

SELECT *
FROM employees
WHERE EXISTS (SELECT *
              FROM employees
              WHERE employee_id = 100);

--
EXISTS 일 경우 예시 (EXISTS: 존재하다)

- WHERE문에 EXISTS는 서브쿼리 테이블의 결과물과 겹치는 데이터만 메인쿼리에 출력 (SELECT에 존재하는것출력)

EXISTS (SELECT 1

               FROM TBL2 B

               WHERE A.ID = B.ID)

-> 서브쿼리 결과와 겹치는 애들만 메인쿼리에 출력

 

--

NOT EXISTS 와 서브쿼리 예시

- WHERE 문에 NOT EXISTS는 서브쿼리 테이블의 결과물을 제외한 나머지를 메인쿼리에 출력
- 메인쿼리에서 서브쿼리의 결과물이랑 겹치는 애들을 제외! ( 차집합)

WHERE NOT EXISTS (SELECT 1

                                      FROM TBL2 B

                                      WHERE A.ID = B.ID)

-> 서브쿼리 결과를 제외하고 출력

 

 

* ANY / ALL 연산자

SELECT *
FROM employees
WHERE salary = ANY(6000, 10000, 12000);
SELECT *
FROM employees
WHERE salary <> ANY(6000, 10000, 12000);
SELECT *
FROM employees
WHERE salary != ANY(6000, 10000, 12000);

> 인라인 뷰(Inline View)

  • FROM 절에 있는 서브쿼리가 인라인 뷰를 생성
  • FROM 절에 직접 기술하여 효율적인 검색 가능
  • FROM 절에 있는 서브쿼리에는 자주 별칭을 사용
SELECT *
FROM employees E, (SELECT department_id
                   FROM departments
                   WHERE department_name = 'IT') D
WHERE E.department_id = D.department_id;
SELECT *
FROM employees E, (SELECT department_id, AVG(salary) avg_sal
                   FROM employees
                   GROUP BY department_id) D
WHERE E.department_id = D.department_id
AND E.salary > D.avg_sal;

Summary

 

  • 서브쿼리
    • 하나의 SQL문 안의 SQL문
    • 단일행 또는 복수행 비교 연산자와 함께 사용 가능
    • 서브쿼리에서는 ORDER BY 사용 불가 (메인쿼리의 마지막 부분에서만 위치 가능하다)
    • 서브쿼리는 메인쿼리의 테이블 칼럼 사용 가능하다. (메인쿼리에서는 서브쿼리의 칼럼 사용불가)
    • 서브쿼리가 SQL 문에서 사용 가능한 곳
      1. SELECT, FROM WHERE, HAVING, ORDER BY 절
      2. INSERT문의 VALUES절
      3. UPDATE문의 SET절
      4. DELETE문은 사용 불가하다.

  • 그 밖의 위치에서 사용 하는 서브 쿼리
    1. SELECT 절에 서브쿼리 사용 → 스칼라 서브쿼리 (Scalar Subquery)
      • 한 행, 한 칼럼만을 반환
      • 값 하나를 반환하는 서브쿼리, SELECT절에 사용하는 서브쿼리
      • 스칼라 서브쿼리 대신 JOIN으로 동일한 결과 추출 가능
    2. 뷰(VIEW)
      • 가상의 테이블, FROM절에 사용하는 뷰는 인라인 뷰 라고 한다.(실제 데이터 X)
      • SQL이 실행될 때만 임시적으로 생성되는 동적 뷰 (일회성)
      • 일반 뷰가 정적 뷰, 인라인 뷰는 동적
      • 장점:
        • 독립성: 테이블 구조 변경 자동 반영
        • 편리성: 쿼리를 단순하게 작성 가능
        • 보안성: 뷰를 생성할 때 칼럼을 제외할 수 있음
728x90
반응형

'Language > RDBMS' 카테고리의 다른 글

[DML_UPDATE] 데이터 변경  (0) 2023.03.03
[DML_INSERT] 데이터 삽입  (0) 2023.03.03
[DML_SELECT] JOIN 연산  (0) 2023.03.03
[DML_SELECT] Multi-Row Function  (0) 2023.03.03
[DML_SELECT] SQL 함수(숫자, 날짜, 변환, 일반)  (0) 2023.03.03

+ Recent posts