서브쿼리
- 하나의 쿼리 문장 내에 또 다른 쿼리문이 들어있는 것
- 하나의 SQL문안에 포함된 또 하나의 QUERY문
- 메인 SQL문을 보조해주는 QUERY문
서브쿼리 사용시 주의사항
- 비교연산자의 오른쪽에 기술해야 하고 반드시 괄호 안에 넣어야 함.
- 메인 쿼리가 실행되기 이전에 한 번만 실행됨.
- 서브쿼리를 괄호로 감싸서 사용한다.
- 서브쿼리는 단일 행 또는 복수 행 비교 연산자와 함께 사용 가능하다.
- 서브쿼리에서는 ORDER BY 를 사용하지 못한다.
서브쿼리가 사용 가능한 곳
1. SELECT 절
2. FROM 절
3. WHERE 절
4. HAVING 절
5. ORDER BY 절
6. INSERT 문의 VALUES 절
7. UPDATE 문의 SET 절
SELECT절 서브쿼리 (스칼라 서브쿼리) |
SELECT절에 서브쿼리 제시 서브쿼리의 결과는 반드시 단일행 OR 집계함수 결과값(단일값 : SUM, COUNT 등) 리턴 -> 서브쿼리의 결과값이 메인쿼리에서 속성으로 SELECT되어야 하기 때문 |
FROM절 서브쿼리 (Inline View) |
FROM 절에 서브쿼리를 제시 서브쿼리를 수행한 결과(RESULT SET)을 테이블로 사용 이 때, 서브쿼리의 결과는 반드시 하나의 테이블로 리턴되어야 함 주로 사용하는 예: TOP N 분석: 데이터베이스 상에 존재하는 자료 중 최상위 몇개 자료를 보기 위해 사용 ROWNUM: 오라클에서 제공해주는 컬럼, 조회된 순서대로 1부터...순번 부여해줌 */ |
중첩 서브쿼리 ( Nested Subqueries ) |
WHERE 절 안에 서브쿼리가 들어있음 가장 자주 쓰이는 대중적인 서브쿼리이며 단일행과 복수행 둘 다 리턴 가능 |
단일행[단일열] 서브쿼리 |
- 서브쿼리의 수행결과가 오직 하나의 행과 열만을 반환 - 이 하나의 결과를 가지고 메인쿼리는 비교연산자를 통해 쿼리를 수행함. - 비교연산자는 단일행 비교연산자를 사용 ( >, >=, <, <=, =, ... ) |
다중행서브쿼리 | 서브쿼리의 수행결과가 두 건 이상의 데이터를 반환. - 비교연산자는다중행 비교연산자를 사용 ( IN, ANY, SOME, ALL, EXISTS ). ==> 서브쿼리를 수행한 결과가 몇행 몇열이냐에 따라 사용가능한 연산자가 달라짐 IN /NOT IN:메인쿼리의 비교조건이 서브쿼리의 결과중에서 하나라도 일치하면 결과 반환 ALL 메인쿼리의 비교조건이 서브쿼리의 검색결과와 모든 값이 일치하면 - 메인쿼리 < ALL ( 서브쿼리 ) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터 전부가 서브쿼리 결과보다 작다면 최소값 반환 - 메인쿼리 > ALL ( 서브쿼리 ) : 서브쿼리의 결과와 비교하여 최대값 반환 ANY 메인쿼리의 비교조건이 서브쿼리의 검색결과와 하나 이상이 일치하면 결과반환 - 메인쿼리 < ANY ( 서브쿼리 ) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 작다면 최소값 반환 - 메인쿼리 > ANY ( 서브쿼리 ) : 서브쿼리의 결과와 비교해 메인쿼리의 데이터중 한개라도 서브쿼리 결과보다 크다면 최대값 반환 EXISTS 메인쿼리의 비교조건이 서브쿼리의 검색결과중에 하나라도 만족하는 값이 존재하면 결과반환 EXISTS 는 해당 로우가 존재하는지의 여부만 확인 IN은 실제 존재하는 데이터들의 모든 값까지 확인 NOT EXISTS는 메인쿼리의 컬럼명과 서브쿼리의 컬럼명을 비교하여 일치하지 않으면 메인쿼리 테이블의 모든 ROW(행)을 반환 |
2) [단일열] 다중행 서브쿼리: 서브쿼리를 수행한 결과값이 여러행일때 - IN : 여러개의 결과값(행) 중에서 하나라도 일치하는 값이 있으면 - NOT IN : 아예 없으면 |
|
3) [단일행] 다중열 서브쿼리 : 서브쿼리를 수행한 결과값이 여러 열일 때 조회 결과값은 한 행이지만 나열된 컬럼수가 여러개일 때 |
|
4) 다중행 다중열 서브쿼리 : 서브쿼리 조회 결과값이 여러행, 여러 컬럼일 경우 |
참고:
https://mjn5027.tistory.com/51#%EB%8B%A8%EC%9D%BC%ED%96%89%20%EC%84%9C%EB%B8%8C%EC%BF%BC%EB%A6%AC
- 다중행
SELECT EMP_NAME, DEPT_CODE, JOB_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE DEPT_CODE = (SELECT DEPT_CODE
FROM EMPLOYEE
WHERE EMP_NAME = '하이유')
AND JOB_CODE = (SELECT JOB_CODE
FROM EMPLOYEE
WHERE EMP_NAME = '하이유');
-- 다중열 서브쿼리
SELECT EMP_NAME, DEPT_CODE, JOB_CODE, HIRE_DATE
FROM EMPLOYEE
WHERE (DEPT_CODE, JOB_CODE) = (SELECT DEPT_CODE, JOB_CODE
FROM EMPLOYEE
WHERE EMP_NAME = '하이유');
--- 다중행
SELECT EMP_ID, EMP_NAME, JOB_CODE, SALARY
FROM EMPLOYEE
WHERE ( JOB_CODE, SALARY ) IN (SELECT JOB_CODE, MIN(SALARY)
FROM EMPLOYEE
GROUP BY JOB_CODE);
-- 인라인뷰
SELECT *
FROM (SELECT EMP_ID, EMP_NAME, (SALARY+SALARY*NVL (BONUS, 0))*12 "보너스연봉", DEPT_CODE
FROM EMPLOYEE )
WHERE "보너스연봉" > 30000000;
SELECT ROWNUM, EMP_NAME, SALARY
FROM (SELECT*
FROM EMPLOYEE
ORDER BY SALARY DESC)
WHERE ROWNUM <=5;
'Database' 카테고리의 다른 글
[SQL] DML - INSERT/ UPDATE /DELETE (0) | 2022.10.04 |
---|---|
[SQL] 제약조건 (CONSTRAINTS) (0) | 2022.10.04 |
[SQL] 집합연산자 (SET OPERATOR) (0) | 2022.10.04 |
[SQL] 조인 (JOIN) (1) | 2022.10.04 |
[SQL] 함수 - 그룹함수 (0) | 2022.10.04 |