하나의 쿼리 안에 존재하는 또 다른 쿼리
SELECT절에 있는 서브쿼리 : 스칼라 서브 쿼리 Scalar Subquery
FROM절에 있는 서브쿼리 : 인라인 뷰 Inline View
WHERE절, HAVING절에 있는 서브쿼리 : 중첩 서브쿼리 Nested Subquery
컬럼대신 오는 서브쿼리.
반드시 하나의 값만 반환되어야함. 안그러면 오류 발생.
서브쿼리를 이용해 해당 테이블에 없는 컬럼을 추가로 반환할 수 있음.
SELECT M.PRODUCT_CODE,
(SELECT S.PRODUCT_NAME FROM PRODUCT S WHERE S.PRODUCT_CODE = M.PRODUCT_CODE) AS PRODUCT_NAME,
M.MEMBER_ID
FROM PRODUCT_REVIEW M;
FROM절 등 테이블명이 올 수 있는 위치에 사용.
하나의 테이블에서 필요한 컬럼만 골라서 새 테이블처럼 사용할 수 있는 방법.
SELECT M.PRODUCT_CODE,
S.PRODUCT_NAME,
S.PRIDE,
M.MEMBER_ID
M.CONTENT
FROM PRODUCT_REVIEW M,
(SELECT PRODUCT_CODE,
PRODUCT_NAME,
PRICE
FROM PRODUCT) S
WHERE M.PRODUCT_CODE = S.PRODUCT_CODE;
WHERE절, HAVING절에 사용.
중첩 서브쿼리는 메인 쿼리와의 관계에 따라 비연관 서브 쿼리, 연관 서브쿼리로 나눌 수 있음.
SELECT NAME, JOB, BIRTHDAY, AGENCY_CODE
FROM ENTERTAINER
WHERE AGENCY_CODE = (SELECT AGNCY_CODE
FROM AGENCY
WHERE AGENCY_NAME = 'SM엔터테인먼트');
SELECT ORDER_NO,
DRINK_CODE,
ORDER_CNT
FROM CAFE_ORDER A
WHERE ORDER_CNT = (SELECT MAX(ORDER_CNT)
FROM CAFE_ORDER B
WHERE B.DRINK_CODE = A.DRINK_CODE);
중첩 서브쿼리는 반환하는 데이터 형태에 따라 단일 행, 다중 행, 다중 컬럼 서브 쿼리로 나눌 수 있음.
단일 행 비교 연산자와 함께 사용 ( =, <, >, <=, >=, <> )
다중 행 비교 연산자와 함께 사용 ( IN, ALLM ANY, SOME, EXISTS )
SELECT *
FROM EMPLOYEES
WHERE (JOB_ID, SALARY) IN (SELECT JOB_ID, MAX_SALARY
FROM JOBS
WHERE MAX_SALARY = 10000);
CREATE OR REPLACE VIEW DEPT_MEMBER AS
SELECT A.DEPARTMENT_ID,
A.DEPARTMENT_NAME,
B.FIRST_NAME,
B.LAST_NAME
FROM DEPARTMENTS A
LEFT OUTER JOIN EMPLOYEES B
ON A.DEPARTMENT_ID - B.DEPARTMENT_ID;
// 만든 DEPT_MEMBER VIEW를 이용하여 아래와 같이 활용가능.
SELECT DEPARTENT_NAME, COUNT(*)
FROM DEPT_MEMBER
GROUP BY DEPARTMENT_NAME
ORDER BY COUNT(*) DESC;
// VIEW 삭제
DROP VIEW DEPT_MEMBER;
SELECT ORDER_DI, ORDER_ITEM, REG_NAME, COUNT(*)
FROM STARBUCKS_ORDER
GROUP BY ROLLUP (ORDER_DT, ORDER_ITEM, REG_NAME)
ORDER BY ORDER_DT;
//위는 날짜별(ORDER_DT), 주문음료별(ORDER_ITEM), 판매사원별(REG_NAME)로 그룹핑 + 날짜별, 주문음료별로 그룹핑 + 날짜별로 그룹핑 + 총합계를 구하는 쿼리.
// ROLLUP 내용에 괄호를 어떻게 처리하느냐에 따라도 결과가 달라짐.
SELECT ORDER_DI, ORDER_ITEM, REG_NAME, COUNT(*)
FROM STARBUCKS_ORDER
GROUP BY ROLLUP ((ORDER_DT, ORDER_ITEM), REG_NAME)
ORDER BY ORDER_DT;
//위와 같이 괄호를 추가하면 날짜별로 그룹핑한 ROW가 빠져서 나옴.
SELECT ORDER_DT,
GROUPING(ORDER_DT),
COUNT(*)
FROM STARBUCKS_ORDER
GROUP BY ROLLUP(ORDER_DT)
ORDER BY ORDER_DT;