Sub Query 서브쿼리
SQL 문 내에서 하위에 존재하는 쿼리이다.
(SQL문 안에 SQL문이 존재한다는 의미.)
서브쿼리는 메인쿼리가 서브쿼리를 포함하는 종속적인 관계이다.
여러번의 쿼리를 수행해야만 얻을 수 있는 결과를
하나의 중첩된 SQL문장으로 간편하게 얻을 수 있다.
select < where < inline (속도차이)
중첩 서브쿼리
WHERE 문에 나타나는 서브쿼리
1. 단일 행
2. 복수(다중) 행
3. 다중 컬럼
--> 하나의 변수(상수)처럼 사용 (서브쿼리의 결과에 따라 달라지는 조건절)
인라인 뷰 (FROM)
FROM 절에 있는 서브쿼리
--> 하나의 테이블처럼 사용 (테이블 대체 용도)
--> 무조건 AS 별칭을 지정해주어야한다.
SELECT
g.g_code
,g.g_name
,g.g_price
,g.g_seller_id
,g.g_reg_date
FROM
tb_goods AS g
JOIN
( SELECT
ROUND(AVG(g.g_price), 0) AS '평균단가'
FROM
tb_goods AS g) AS gAvg
WHERE
g.g_price > gAvg.평균단가;
스칼라 서브쿼리 (SELECT)
SELECT 문에 있는 서브쿼리 (1행만 반환된다)
--> 하나의 컬럼처럼 사용 (표현 용도)
SELECT
g.g_code
,g.g_name
,g.g_price
,g.g_seller_id
,g.g_reg_date
FROM
(SELECT
*
,(SELECT
ROUND(AVG(gAvg.g_price),0)
FROM
tb_goods AS gAvg) AS '평균단가'
FROM
tb_goods) AS g
WHERE
g.g_price > g.평균단가;
FROM 절에 인라인 뷰 안의
SELECT문에 스칼라 서브쿼리가 있다.
1. 단일 행 서브쿼리
서브쿼리 결과값이 1개
SELECT
*
FROM
tb_member AS m
WHERE
m.m_level = ( SELECT
l.level_num
FROM
tb_member_level AS l
WHERE
l.level_num = 1 );
실행순서는
서브쿼리 실행 -> 메인(부모)쿼리 실행된다.
서브쿼리는 SELECT 문으로만 작성할 수 있다.
반드시 괄호 () 안에 존재하여야 한다.
괄호가 끝나고 끝에 세미콜론 ; 을 쓰지않는다.
ORDER BY 를 사용할 수 없다.
2. 다중 행 서브쿼리 (IN)
IN : 리턴되는 값 중 조건에 해당하는 값이 있으면 true
SELECT
*
FROM
tb_member AS m
WHERE
m.m_level IN ( SELECT
l.level_num
FROM
tb_member_level AS l );
서브쿼리 결과가 여러 개
ex)
m.m_level = 1
or m.m_level = 2
or m.m_level = 3
2. 다중 행 서브쿼리 (ANY, SOME)
ANY, SOME : 서브쿼리에 의해 리턴되는 각각의 값과 조건을 비교하여 하나 이상을 만족하면 true
(SOME : ANY 의 Alias(별칭) -> 둘 다 결과는 같다)
SELECT
m.*
FROM
tb_member AS m
WHERE
m.m_level = ANY( SELECT
l.level_num
FROM
tb_member_level AS l
WHERE
l.level_num > 1);
= ANY
IN과 같은 결과 (2, 3)
ex) m.m_level IN (2,3)
> ANY
IN과 다른 결과 (2, 3)
ex) m.m_level > 2 or m.m_level > 3
3. 다중 행 서브쿼리 (ALL)
ALL : 값을 서브쿼리에 의해 리턴되는 모든 값과
조건 값을 비교하여 모든 값을 만족해야만 함.
SELECT
m.*
FROM
tb_member AS m
WHERE
m.m_level > ALL( SELECT
l.level_num
FROM
tb_member_level AS l
WHERE
l.level_num < 3);
IN과 다른 결과 (1, 2)
ex) m.m_level > 1 AND m.m_level > 2
4. 다중 행 서브쿼리 (EXISTS)
EXISTS : 메인 쿼리의 비교조건이 서브쿼리의 결과 중에서 만족하는 값이 하나라도 존재하면 true
where 조건절 밑에 쓰여야한다.
SELECT
m.*
FROM
tb_member AS m
WHERE
EXISTS ( SELECT
l.level_num
FROM
tb_member_level AS l
WHERE
l.level_num < 3 AND m.m_level = l.level_num);
IN과 같은 결과 (1, 2)
Ex) m.m_leve IN ( 1, 2)
5. 다중 컬럼 서브쿼리
서브 컬럼 결과가 여러개 이다.
SELECT
*
FROM
tb_member AS m1
WHERE
(m1.m_id, m1.m_level) IN ( SELECT
m2.m_id
,MIN(m2.m_level)
FROM
tb_member AS m2 );