[Database] SubQuery

h220101·2022년 5월 1일
0
post-thumbnail

Sub Query 서브쿼리

SQL 문 내에서 하위에 존재하는 쿼리이다.
(SQL문 안에 SQL문이 존재한다는 의미.)
서브쿼리는 메인쿼리가 서브쿼리를 포함하는 종속적인 관계이다.
여러번의 쿼리를 수행해야만 얻을 수 있는 결과를
하나의 중첩된 SQL문장으로 간편하게 얻을 수 있다.

  • 서브쿼리(자식쿼리) - 메인쿼리 컬럼사용가능
  • 메인쿼리(부모쿼리) - 서브쿼리 컬럼사용불가
    java 상속과 같은 개념이다.

select < where < inline (속도차이)


Sub Query 종류

중첩 서브쿼리

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 );
profile
기록하는 삶

0개의 댓글