///////
Search
2️⃣

SELECT 구문 내의 SELECT 구문(서브쿼리)

서브쿼리(Sub Query)

완전한 문장으로 구성된 구문 안에 또 하나의 완전한 구문이 있는 것
중간 결과물을 생성한다.
안에서부터 밖으로 정리한다.
쿼리의 각 부분을 명확히 구분할 수 있다.
SELECT 구문 안에 SELECT 구문이 있는것을 볼 수 있다. 저 부분이 서브 쿼리이다.
서브쿼리를 먼저 수행하고 외부 SELECT 구문을 수행한다.
서브쿼리의 결과가 외부 쿼리의 구문에 사용됨. → WHERE 절 서브쿼리

서브쿼리의 종류

1.
WHERE 절 서브쿼리 (중첩 서브쿼리) (단일 행 서브쿼리 / 다중 행 서브쿼리)
2.
FROM 절 서브쿼리 (인라인 뷰)
3.
SELECT 절 서브쿼리 (스칼라 서브쿼리)

1. WHERE 절 서브쿼리 (중첩 서브쿼리) (단일 행 서브쿼리 / 다중 행 서브쿼리)

서브쿼리의 결과물을 외부 구문 필터링 값으로 사용한다.
서브쿼리 중 가장 일반적인 서브쿼리문
결과물이 단일 행인 경우 → 단일 행 서브쿼리
결과물이 다중 행인 경우 → 다중 행 서브쿼리
SELECT GD_NAME FROM GOODS WHERE GD_ID IN (SELECT OD_GOODS_ID FROM ORDER_LIST GROUP BY OD_GOODS_ID);
SQL
복사
위 예시에서 다음과 같은 쿼리를 작성하면
--WHERE 절 서브쿼리 (SELECT OD_GOODS_ID FROM ORDER_LIST GROUP BY OD_GOODS_ID);
SQL
복사
내부의 서브쿼리문이 먼저 수행되며 다음과 같은 결과가 나온다.
위 중간 결과물은 외부 SELECT 구문에서 사용된다.
SELECT GD_NAME FROM GOODS WHERE GD_ID IN (1, 2, 3)
SQL
복사

2. FROM 절 서브쿼리 (인라인 뷰)

하나의 테이블을 리턴하는 서브쿼리
테이블을 리턴함으로써 임시 테이블로 사용한다.
SELECT GD_NAME FROM GOODS WHERE GD_ID IN (SELECT OD_GOODS_ID FROM (SELECT OD_GOODS_ID, SUM(OD_QUANTITY) as quantity FROM ORDER_LIST GROUP BY OD_GOODS_ID HAVING quantity >= 3) );
SQL
복사
위 코드를 예시로 보면 WHERE 절 안의 서브쿼리에 FROM 절 서브쿼리가 들어있다.
가장 내부의 FROM 절 서브쿼리를 먼저 수행한다.
-- FROM 절 서브쿼리 SELECT OD_GOODS_ID, SUM(OD_QUANTITY) as quantity FROM ORDER_LIST GROUP BY OD_GOODS_ID
SQL
복사
FROM 절의 서브쿼리를 수행하면 다음과 같은 결과가 나온다.
이후 HAVING quantity >= 3 을 수행하면 다음과 같은 결과가 나온다.
아래 결과를 중간 결과물 A 라고 하자.
이제 FROM 절을 수행한다.
SELECT OD_GOODS_ID FROM 중간결과물A
SQL
복사
마지막으로 외부 SELECT 구문을 수행한다.
SELECT GD_NAME FROM GOODS WHERE GD_ID IN 2
SQL
복사

3. SELECT 절 서브쿼리 (스칼라 서브쿼리)

서브쿼리의 결과값은 단일 행, 단일 열의 스칼라값으로 리턴
리턴된 결과값을 메인 쿼리에서 SELECT 한다.
결과가 없는 경우 NULL을 리턴
불필요한 JOIN 을 막기위해 사용
SELECT GD_NAME, (SELECT COUNT(*) FROM ORDER_LIST WHERE OD_GOODS_ID = GD_ID) AS count FROM GOODS;
SQL
복사
스칼라 서브쿼리는 중간 연산 과정에서 각 행마다 결과값을 도출해야 하기 때문에 서브 쿼리가 여러 번 실행된다.
위 쿼리의 경우, OD_GOODS_ID = GD_ID 에 해당하는 GD_ID 마다 쿼리문을 수행한다.

행의 존재 여부 확인방법

Exist

서브 쿼리의 결과 집합에 하나의 행이라도 존재한다면 1 , 존재하지 않으면 0 을 리턴한다.
SELECT EXISTS (SELECT * FROM GOODS WHERE GD_NAME = '흰색 반팔티') as isExist;
SQL
복사
위 쿼리를 실행 시 결과는 다음과 같다.