[Oracle] SQL 서브쿼리 SELECT절, FROM절, WHERE절
서브쿼리
- 하나의 쿼리 문장 내에 포함된 또 하나의 쿼리 문장.
- 비교연산자의 오른쪽에 기술해야 하고 반드시 괄호 안에 넣어야 함.
- 메인 쿼리가 실행되기 이전에 한 번만 실행됨.
서브쿼리는 크게 2가지 혹은 4가지로 나누어질 수 있다.
- 단일행 서브쿼리( 단일행 단일열 서브쿼리 OR 단일행 다중열 서브쿼리)
- 다중행 서브쿼리( 다중행 단일열 서브쿼리 OR 다중행 다중열 서브쿼리)
SELECT 절 서브쿼리 ( 스칼라 서브쿼리 )
스칼라 서브쿼리 ( Scalar Subqueries ) 라고 불리며 SELECT 절 안에 서브쿼리가 들어있다.
이 때, 서브쿼리의 결과는 반드시 단일행 단일열 서브쿼리나 SUM, COUNT 등의 집계 함수를 거친 단일값의 형태로 리턴되어야 한다.
왜냐하면, 서브쿼리를 끝마친 값하나를 메인쿼리에서 SELECT 하기 때문이다.
예를 들어 홍길동이라는 이름을 가진 학생의 학과 이름을 출력하는 서브쿼리절은 다음과 같다.
SELECT 학생이름,
( SELECT 학과.학과이름
FROM 학과
WHERE 학과.학과ID = 학생.학생ID ) AS 학과이름
FROM 학생
WHERE 학생이름 = '홍길동';
FROM 절 서브쿼리 ( 인라인뷰 서브쿼리 )
인라인뷰 ( Inline Views ) 라고 불리며 FROM 절 안에 서브쿼리가 들어있다.
이 때, 서브쿼리의 결과는 반드시 하나의 테이블로 리턴되어야 한다.
이유는 서브쿼리를 끝마친 테이블 하나를 메인쿼리의 FROM 에서 테이블로 잡기 때문.
다음은 '수학' 과목을 수강하고 있는 학생의 이름과 수학 점수를 출력하는 서브쿼리의 형태이다.
SELECT 학생이름, 수학점수
FROM ( SELECT 학생.학생이름 AS 학생이름,
과목.과목점수 AS 수학점수
FROM 학생, 과목
WHERE 학생.학생이름 = 과목.학생이름
AND 과목.과목이름 = '수학' ) ;
WHERE 절 서브쿼리 ( 중첩 서브쿼리 )
중첩 서브쿼리 ( Nested Subqueries ) 라고 불리며 WHERE 절 안에 서브쿼리가 들어있다.
가장 자주 쓰이는 서브쿼리로, 단일행과 복수행 둘 다 리턴이 가능하다.
주로 서브쿼리를 끝마친 값들을 메인쿼리의 조건절을 통해 비교등을 위해 사용한다.
수학 과목을 수강하는 학생들의 모든 정보를 조회한다고 가정하면 다음과 같다.
SELECT *
FROM 학생
WHERE 학생.학생이름 IN ( SELECT 과목.학생이름
FROM 과목
WHERE 과목.과목이름 = '수학' ) ;
단일행 서브쿼리
- 서브쿼리의 수행결과가 오직 하나의 ROW(행)만을 반환.
- 이 하나의 결과를 가지고 메인쿼리는 비교연산자를 통해 쿼리를 수행함.
- 비교연산자는 단일행 비교연산자를 사용 ( >, >=, <, <=, =, ... ).
SELECT EMP_NAME, SALARY
FROM EMPLOYEE
WHERE SALARY > (SELECT AVG(SALARY)
FROM EMPLOYEE );
다중행 서브쿼리
- 서브쿼리의 수행결과가 두 건 이상의 행 데이터를 반환.
- 비교연산자는 다중행 비교연산자를 사용 ( IN, ANY, SOME, ALL, EXISTS ).
** 출력되는 서브쿼리의 값이 10, 20, 30, 40이라고 가정했을 때,
IN(일치의 의미)
메인쿼리의 비교조건이 서브쿼리의 결과중에서 하나라도 일치하면 참이다.
메인쿼리 IN (10, 20, 30, 40) 서브쿼리 : 메인쿼리의 값 중에서 10, 20, 30, 40 중에 하나라도 일치하는 '값'이 있다면 참.
ALL(모든의 의미)
메인쿼리의 비교조건이 서브쿼리의 검색결과와 모든 값이 일치하면 참.
- 메인쿼리 < ALL (10, 20, 30, 40) 서브쿼리 : 메인쿼리가 서브쿼리의 결과 모두와 비교하여도 작다면 최소값 반환.
- 메인쿼리 > ALL (10, 20, 30, 40) 서브쿼리 : 메인쿼리가 서브쿼리의 결과 모두와 비교하여도 크다면 최대값 반환.
ANY(하나라도의 의미)
메인쿼리의 비교조건이 서브쿼리의 검색결과와 하나 이상이 일치하면 참.
- 메인쿼리 < ANY (10, 20, 30, 40) 서브쿼리 : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 작다면 최소값 반환.
- 메인쿼리 > ANY (10, 20, 30, 40) 서브쿼리 : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 크다면 최대값 반환.
EXISTS(존재의 의미)
메인쿼리의 비교조건이 서브쿼리의 검색결과중에 하나라도 만족하는 값이 존재하면 참.
IN과 EXISTS의 차이는
- EXISTS 는 해당 행이 존재하는지의 여부를 확인.
- IN은 실제 존재하는 데이터들의 모든 값까지 확인.
NOT EXISTS는 메인쿼리의 컬럼명과 서브쿼리의 컬럼명을 비교하여 일치하지 않으면 메인쿼리 테이블의 모든 행을 반환한다.
'DB' 카테고리의 다른 글
[Oracle] 오라클 VIEW 생성 및 사용법 정리 (DML-insert, update 포함) (0) | 2022.03.31 |
---|---|
[Oracle] SQL의 단일행 함수 정리(문자열 관련, 숫자 관련, 날짜 관련, 형변환 관련, NULL 처리, 선택 관련 함수), 그룹 함수 정리 (0) | 2022.03.23 |