SQL 서브쿼리 정리(중첩 서브쿼리, 인라인 뷰, 스칼라 서브쿼리)

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);
  1. 서브쿼리: HR.DEPARTMENTS 테이블에서 LOCATION_ID가 1700인 DEPARTMENT_ID를 SELECT
  2. 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