-> 블로그 이전

[SQLD] 2-13. 서브쿼리

2021. 11. 2. 16:47Certificate`/SQLD

서브쿼리

- 하나의 SQL문에 포함된 또 다른 SQL문 (중첩)

- 알려지지 않은 기준을 이용한 검색을 위해 사용

- 괄호로 감싸서 사용

- 단일 행/복수 행 비교 연산자와 함께 사용 가능

- 단일 행 비교연산자 서브 쿼리의 결과는 반드시 1건 이하

- ORDER BY 사용 X

- SELECT / FROM / WHERE / HAVING / ORDER BY / INSERT(VALUES) / UPDATE(SET)절에서 사용 가능

 

※ 메인 쿼리 / 서브 쿼리

- 메인쿼리

  • 서브쿼리의 컬럼 사용 X

- 서브쿼리

  • 메인쿼리의 컬럼 사용 O
  • 항상 메인쿼리 레벨로 결과 집합 생성 -> 조직(1), 사원(M) -> 결과 집합 (1)

※ 질의결과(SELECT 메인)에 서브쿼리 컬럼 표시 방법

- 조인 방식으로 변환

- 함수, 스칼라 서브쿼리 등 사용

 

서브쿼리 분류

≫ 동작 방식

- 비연관 서브쿼리

  • 메인쿼리 컬럼을 가지고 있지 않은 형태의 서브쿼리
  • 메인쿼리에 값 제공을 위한 목적

- 연관 서브쿼리

  • 메인쿼리 컬럼을 가지고 있는 형태의 서브쿼리
  • 메인쿼리 결과 데이터를 서브쿼리에서 조건이 맞는지 확인

≫ 반환되는 데이터 형태

단일 행 서브쿼리

  • 실행결과가 항상 1건 이하인 서브쿼리
  • 단일 행 비교 연산자(=, <, <=, >, >=, <>)와 함께 사용

다중 행 서브쿼리 

  • 실행결과가 여러 건인 서브쿼리
  • 다중 행 비교 연산자(IN, ALL, ANY, SOME, EXISTS)와 함께 사용

다중 컬럼 서브쿼리 

  • 실행 결과가 여러 컬럼인 서브쿼리
  • 메인쿼리의 조건절에 여러 컬럼 동시에 비교 가능
  • 서브쿼리와 메인쿼리와 비교하고자 하는 컬럼 개수/위치가 동일해야 한다

 

단일 행 서브쿼리

- 결과가 2건 이상이면 실행시간(Run Time) 오류 발생 (컴파일 시 알 수 없는 오류)

- 테이블 전체에 하나의 그룹 함수를 적용하면 결과가 1건이기 때문에 단일 행 서브쿼리로 사용 가능

'정남일'이 동명이인이라면 2건 이상의 결과가 리턴되어서 오류 발생 / 그룹함수 사용(AVG)

 

다중 행 서브쿼리

- 반드시 다중 행 비교 연산자(IN, ALL, ANY, SOME)와 함께 사용

다중 행 연산자 설명
IN (서브쿼리) - 서브쿼리 결과에 존재하는 값과 동일한 조건 
- 서브쿼리 + 단일 값도 사용 가능
비교 연산자 ALL (서브쿼리) - 서브쿼리 결과에 존재하는 모든 값을 만족하는 조건
비교 연산자 ANY/SOME (서브쿼리) - 서브쿼리 결과에 존재하는 어느 하나의 값이라도 만족하는 조건
EXISTS (서브쿼리) - 서브쿼리의 결과를 만족하는 값이 존재하는지 여부 확인
- 1건이라도 만족하는 값 찾으면 더 이상 검색 X
- 서브쿼리에서 조인 사용

≫ '정현수'라는 선수가 소속되어 있는 팀 정보 출력 

- IN (서브 쿼리)

1. '정현수'라는 선수가 소속

2. (1)이 소속되어 있는 팀의 정보

- '정현수'라는 이름을 가진 선수가 2명 존재하기 때문에 다중 행 비교 연산자 IN 사용

30번 부서 사원 중 급여를 가장 많이 받는 사원보다 더 많은 급여를 받는 사람의 이름과 급여를 출력

- 비교 연산자 ALL (서브쿼리)

1. 30번 부서 사원 중 급여를 가장 많이 사원

2. (1)보다 더 많은 급여를 받는 사원들의 이름, 급여

(1) / 단일 행 서브쿼리(그룹함수 MAX) 사용 / 다중 행 서브쿼리 사용(ALL)

부서번호 30번 사원 급여 중 가장 낮은 값(950)보다 높은 급여를 받는 사원들의 이름, 급여를 출력

- 비교연산자 ANY (서브쿼리)

1. 30번 사원 급여 중 가장 낮은 값

2. (1)보다 높은 급여를 받는 사원들의 이름, 급여

(1) / 단일 행 서브쿼리(그룹함수 MIN) 사용 / 다중 행 서브쿼리 사용(ANY)

 

다중 컬럼 서브쿼리

- 여러 개의 컬럼이 리턴되어 메인쿼리의 조건과 동시에 비교

 

소속팀별 키가 가장 작은 사람들의 정보

1. 소속팀별 키가 가장 작은 사람

2. (1)의 정보

 

SELECT 절에 서브쿼리 사용 (스칼라 서브쿼리)

스칼라 서브쿼리

- 단일 행 서브쿼리

- 1행, 1컬럼 반환 (1 Row 1 Column)

- 메인쿼리의 결과 건수만큼 반복수행

 

FROM 절에 서브쿼리 사용 (인라인 뷰)

인라인 뷰

- SQL문이 실행될 때만 일시적으로 생성되는 동적인 뷰

- DB에 해당 정보 저장 X

- 테이블 명이 올 수 있는 곳에서 사용 가능

- 조인 방식과 비슷

- ORDER BY 사용 가능

 

뷰 (View)

- 실제 데이터를 가지고 있지 않고 테이블이 수행하는 역할 수행 (가상 테이블)

- 뷰 정의를 참조해서 DBMS 내부적으로 질의를 재작성

- 이미 존재하는 뷰를 참조해서 생성 가능

- 데이터를 저장하지 않고 데이터 조회 가능

 

장점 (독-편-보)

장점 설명
독립성 - 테이블 구조가 변경되어도 뷰를 사용하는 응용프로그램은 변경 안해도 된다
편리성 - 복잡한 질의를 뷰로 생성함으로써 관련 질의를 단순하게 작성 가능
보안성 - 숨기고 싶은 정보가 존재하면, 뷰를 생성할 때 해당 컬럼을 빼고 생성

 

뷰 생성

-- 뷰 생성
CREATE VIEW V_PLAYER_TEAM AS
SELECT P.PLAYER_NAME, P.POSITION, P.BACK_NO, P.TEAM_ID, T.TEAM_NAME
FROM PLAYER P, TEAM T
WHERE P.TEAM_ID = T.TEAM_ID;
------------------------------------------------------------------
-- 이미 존재하는 뷰 참조해서 생성
CREATE VIEW V_PLAYER_TEAM_FILTER AS
SELECT PLAYER_NAME, POSITION, BACK_NO, TEAM_NAME
FROM V_PLAYER_TEAM
WHERE POSITION IN('GK','MF');

뷰 테이블 사용 / 인라인 뷰 사용

뷰 제거

DROP VIEW V_PLAYER_TEAM;
DROP VIEW V_PLAYER_TEAM_FILTER;