728x90
강의: 유튜브 SQL전문가 정미나
https://www.youtube.com/watch?v=oc-ya1MpK5c
서브 쿼리
- 하나의 SQL문안에 포함되어 있는 또 다른 SQL문, 알려지지 않은 기준을 이용한 검색에 사용
- 서브쿼리를 괄호로 감싸서 사용한다
- 쓰이는 위치에 따라서 중첩 서브쿼리, 인라인 뷰, 스칼라 서브쿼리로 나뉜다.
1. 중첩 서브쿼리(WHERE절, HAVING절)
형식: WHRER 컬럼명 IN (서브쿼리)
# 예시
SELECT *
FROM HR.EMPLOYEES AS A
WHERE A.DEPARTMENT_ID = (SELECT B.DEPARTMENT_ID
FROM HR.DEPARTMENTS AS B
WHERE B.LOCATION_ID = 1700);
- 서브쿼리: HR.DEPARTMENTS 테이블에서 LOCATION_ID가 1700인 DEPARTMENT_ID를 SELECT
- DEPARTMENT_ID를 가지는 사원을 조회함
서브쿼리의 성능
- 서브쿼리는 성능 문제와는 관계 없음
- 서브쿼리나 조인 상관 없이 옵티마이저가 알아서 판단함
- BUT 서브쿼리를 사용하면 안 되는 경우 존재
# 예시
SELECT A.EMPLOYEE_ID, A.FIRST_NAME, A.LAST_NAME, A.SALARY
FROM HR.EMPLOYEES A
WHERE A.SALARY = (SELECT MIN(SALARY) FROM HR.EMPLOYEES)
OR A.SALARY = (SELECT MAX(SALARY) FROM HR.EMPLYEES);
위 쿼리의 문제점
- 메인쿼리와 서브쿼리의 테이블이 동일
- 하나의 쿼리 안에서 테이블 3번 접근
- 비효율적임
# 수정
SELECT B.EMPLOYEE_ID, B.FIRST_NAME, B.LAST_NAME, B.SALARY
FROM (
SELECT A.EMPLOYEE_ID,
A.FIRST_NAME,
A.LAST_NAME,
A.SALARY,
ROW_NUMBER() OVER(ORDER BY SALARY) MINSAL,
ROW_NUMBER() OVER(ORDER BY SALARY DESC) MAXSAL
FROM HR.EMPLOYEES AS A
) AS B
WHERE B.MINSAL = 1 OR B.MAXSAL = 1;
2. 인라인 뷰(FROM절)
- 인라인 뷰를 남발하지 않고 적절히 사용하면 비용 절감의 큰 효과가 있음
- ex) 두 테이블을 조인하는 경우 전체 데이터를 조인해서 필요없는 부분을 버리는 것보다는 필요한 데이터만 인라인 뷰로 생성해서 조인하면 비용절감의 효과가 생김
# 예시
SELECT A.DEPARTMENT_NAME,
B.AVG_SAL
FROM DEPARTMENTS A,
(SELECT DEPARTMENT_ID,
ROUND(AVG(SALARY),2) AVG_SAL
FROM EMPLOYEES
GROUP BY DEPARTMENT_ID) B
WHERE A.DEPARTMENT_ID = B.DEPARTMENT_ID
3. 스칼라 서브쿼리(SELECT절)
- 하나의 레코드 당 하나의 값을 리턴
- 주로 SELECT절에 쓰임
# 형태
SELECT 컬럼1, 컬럼2, (SELECT B.컬럼
FROM 테이블 B
WHERE A.컬럼 = B.컬럼)
FROM 테이블 1
WHERE 조건;
728x90