서브쿼리
•
다른 쿼리 내부에 포함되어 있는 괄호()로 감싸진 SELECT문을 의미합니다.
•
서브쿼리를 포함하고 있는 메인쿼리를 외부쿼리라고 부르고 서브쿼리는 내부쿼리라고도 부릅니다.
•
일반적으로 서브쿼리는 JOIN보다 성능이 좋지 않기 때문에 남발하는 것은 좋지 않습니다.
서브 쿼리가 사용 가능한 곳
•
서브쿼리를 포함할 수 있는 외부쿼리
◦
SELECT, INSERT, UPDATE, DELETE, SET, DO
•
서브쿼리 안에서 포함시켜 사용할 수 있는 곳
◦
SELECT, FROM, WHERE, HAVING, ORDER BY
◦
INSERT문의 VALUES
◦
UPDATE문의 SET
특징
•
실행 순서는 서브쿼리 → 메인쿼리순으로 실행됩니다.
•
서브쿼리는 메인쿼리의 컬럼을 사용 가능
•
메인쿼리는 서브쿼리의 컬럼을 사용 불가능
•
서브쿼리 끝엔 세미콜론(;)을 붙이지 않습니다.
•
ORDER BY를 사용할 수 없습니다.
장점
•
쿼리를 구조화시키므로 쿼리의 각 부분을 명확히 구분할 수 있게 해줍니다.
•
복잡한 JOIN이나 UNION과 같은 동작을 수행할 수 있는 또 다른 방법을 제공합니다.
•
복잡한 JOIN이나 UNION보다 더 가독성이 좋습니다.
서브쿼리의 종류
-- 스칼라 서브쿼리
SELECT [컬럼이름], (SELECT ...) -- 컬럼처럼 사용 (표현 용도)
-- 인라인 뷰
FROM (SELECT ...) AS [별명] -- 테이블처럼 사용 (테이블 용도)
-- 중첩 서브쿼리
WHERE [컬럼 = (SELECT ...)] -- 변수(상수)처럼 사용 (조건 용도)
SQL
복사
스칼라 서브쿼리
•
SELECT문에 사용하는 서브쿼리로 반드시 하나의 값만 출력되도록 작성해야 합니다.
•
일치하는 데이터가 없더라도 NULL값을 리턴할 수 있습니다.
SELECT film_id, title, description, (
SELECT length
FROM film AS f
WHERE ft.film_id = f.film_id) AS length
FROM film_text AS ft;
SQL
복사
인라인 뷰
•
FROM절에 사용하는 서브쿼리로 반드시 별명을 지정해주어야 합니다.
SELECT film_id, title, description
FROM (
SELECT *
FROM film
WHERE rental_rate = 4.99) AS f;
SQL
복사
중첩 서브쿼리
•
WHERE절에 사용하는 서브쿼리입니다.
•
단일 행 서브쿼리
◦
서브쿼리 결과로 한 개의 행을 외부쿼리에 반환합니다.
SELECT *
FROM film_category
WHERE category_id = (
SELECT category_id
FROM category
WHERE name = 'Action');
SQL
복사
•
다중 행 서브쿼리
◦
서브쿼리 결과로 여러 행을 외부쿼리에 반환해 IN, ANY, ALL, EXISTS 등의 연산자로 활용합니다.
SELECT film_id, title, description
FROM film
WHERE film_id IN (
SELECT film_id
FROM film_actor
WHERE actor_id = 1);
SQL
복사
•
다중 컬럼 서브쿼리
◦
서브쿼리 결과로 여러 컬럼의 행을 외부쿼리에 반환합니다.
◦
서브쿼리와 외부쿼리의 비교 컬럼 개수가 같아야 합니다.
◦
외부쿼리의 컬럼은 괄호 ()로 묶어주어야 합니다.
SELECT ord_num, agent_code, ord_date, ord_amount
FROM orders
WHERE (agent_code, ord_amount) IN
(SELECT agent_code, MIN(ord_amount)
FROM orders
GROUP BY agent_code);
SQL
복사