제수기 - 제발 수업내용을 기억해라 / 수업필기
SQL문(main-query) 안에 포함되어 있는 또 다른 SQL문(sub-query)
<<서브쿼리 유형 3가지>>
1. 일반 서브쿼리
1) 단일행 일반 서브쿼리
2) 다중행 일반 서브쿼리
2. 상관 서브쿼리
1) 스칼라 서브쿼리
3. 인라인뷰(파생테이블)
<<규칙>>
-- 서브쿼리는 반드시 소괄호로 묶어야 함 - (SELECT ... ) 형태
-- 서브쿼리 내에서 order by 문법은 지원 안됨
# 개념 맛보기
from
-> where
-> 서브쿼리
를 만났으니 바로 실행 -> 그 값을 활용해서 메인쿼리
의 select
를 마저 실행<일반서브쿼리와 상관서브쿼리 구분>
-- 메인쿼리에 있는 것을 서브쿼리에서 가져다 쓰면 상관 서브쿼리 (블럭 잡아 단독으로 실행할수 없다.)
-- 그렇지 않고 서브쿼리가 독단적으로 사용이 되면 일반 서브쿼리
- 단일행 서브쿼리 : 서브쿼리 실행결과가 1행인 경우
- 다중행 서브쿼리 : 서브쿼리 실행결과가 여러행인 경우
<다중행 이해돕기>
category_code
는 1개의 행이지만 select category_code
는 4개 행이 있어서 에러가 났다. =
연산자가 잘못 놓인 탓이다.in
연산자를 사용해야 한다. in
을 썼더니 에러가 해결됐다.-- all(다중행 서브쿼리): 서브쿼리의 모든 결과값을 의미.
비교연산자와 사용시, 최소/최대값을 가진 행을 쉽게 조회할 수 있다.
-- 메인쿼리의 값을 서브쿼리에 주고 서브쿼리를 수행한 다음
-- 그 결과를 다시 메인쿼리로 반환하는 방식으로 수행되는 서브쿼리
헷갈리니까 흐름을 써보자
from
에서 tbl_menu
를 불러옴 -> where
에서 menu_price
<서브쿼리> 실행 -> <서브쿼리> from
에서 tbl_menu
불러오고, where
에서 category_code
=
<메인쿼리>에서 불러온 tbl_menu
의 category_code
와 같은지 확인한 뒤에 <서브쿼리>의 select
에서 max(menu_price)
실행🔍<메인쿼리>는 from - where - 절로 행을 하나씩 다 살펴보게 된다. 즉, menu_price
와 <서브쿼리>의 max(menu_price)
가 category_code
에서 부합하는 게 있는지 행을 하나씩 다 살펴보면서 찾게 된다.
하나씩 뜯어보기
모든 행을 볼 건데, <메인쿼리> tbl_menu
테이블에서 menu_price
가 뭐랑 같은 지 <서브쿼리> 비교해서 계속 돌려볼거야.
<서브쿼리>에서 category_code
랑 <메인쿼리>에서 불러온 m.category_code
랑 같을 때, menu_price
가 max
인 값을 찾으면 True
니까 결과값이 결과집합에 들어가는거고, max
가 아니면 False
니까 결과값이 결과집합에 들어가지 않는거지.
이해를 돕기 위해 <서브쿼리>를 따로 빼서 직접 4
라는 값을 category_code
로 줘보자. 그러면 4
라는 카테고리에서 가장 큰 값인 20000
이 나와.
<메인쿼리>랑 <서브쿼리>가 행마다 category_code
비교해서 max(menu_price)
찾다가 <서브쿼리>에서 가장 큰 값이 나올 때 그걸 결과값으로 뱉어내는 형식인거야.
exists(상관서브쿼리) : 상관서브쿼리의 반환된 행이 있다면 True, 없으면 False
FROM절에 서브쿼리를 사용한 것을 인라인뷰(INLINE-VIEW)라고 한다.
<VIEW란?>
-- 실제테이블을 주어진 뷰('보다'라는 의미를 가짐)를 통해 제한적으로 사용가능함.
-- 실제테이블에 근거한 논리적인 가상테이블(사용자에게 하나의 테이블처럼 사용가능)이다.
-- view 를 사용하면 복잡한 쿼리문을 간단하게 만듦으로써 가독성이 좋으므로 편리하게 쿼리문을 만들수 있다.
별칭
필수인라인뷰
에 작성되지 않은 컬럼은 select
에 사용할 수 없다. 왜냐면 view
로 한정해서 테이블을 보도록 했기 때문이다.별칭
을 줬으면 이걸 컬럼명처럼 써야 함-- with 구문을 이용해서 inline view를 선언하고, 재사용한다.