제수기 > SQL > DML/DQL > SUBQUERY

Eunbi Jo·2024년 12월 26일
0

제수기

목록 보기
15/90
제수기 - 제발 수업내용을 기억해라 / 수업필기

SUBQUERY

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 연산자

-- all(다중행 서브쿼리): 서브쿼리의 모든 결과값을 의미. 
	비교연산자와 사용시, 최소/최대값을 가진 행을 쉽게 조회할 수 있다.
  • min/max는 행을 조회해주는 건 아니고 값을 알려준다.
  • all은 행을 조회해준다.

상관 서브쿼리

-- 메인쿼리의 값을 서브쿼리에 주고 서브쿼리를 수행한 다음
-- 그 결과를 다시 메인쿼리로 반환하는 방식으로 수행되는 서브쿼리

  • 카테고리별 가격이 가장 비싼 메뉴 조회

    헷갈리니까 흐름을 써보자
    <메인쿼리> from에서 tbl_menu를 불러옴 -> where에서 menu_price <서브쿼리> 실행 -> <서브쿼리> from에서 tbl_menu 불러오고, where에서 category_code = <메인쿼리>에서 불러온 tbl_menucategory_code 와 같은지 확인한 뒤에 <서브쿼리>의 select에서 max(menu_price) 실행
    ...

🔍<메인쿼리>는 from - where - 절로 행을 하나씩 다 살펴보게 된다. 즉, menu_price와 <서브쿼리>의 max(menu_price)category_code에서 부합하는 게 있는지 행을 하나씩 다 살펴보면서 찾게 된다.

하나씩 뜯어보기

  • 모든 행을 볼 건데, <메인쿼리> tbl_menu 테이블에서 menu_price가 뭐랑 같은 지 <서브쿼리> 비교해서 계속 돌려볼거야.

  • <서브쿼리>에서 category_code랑 <메인쿼리>에서 불러온 m.category_code랑 같을 때, menu_pricemax인 값을 찾으면 True니까 결과값이 결과집합에 들어가는거고, max가 아니면 False니까 결과값이 결과집합에 들어가지 않는거지.

  • 이해를 돕기 위해 <서브쿼리>를 따로 빼서 직접 4라는 값을 category_code로 줘보자. 그러면 4라는 카테고리에서 가장 큰 값인 20000이 나와.

  • <메인쿼리>랑 <서브쿼리>가 행마다 category_code 비교해서 max(menu_price) 찾다가 <서브쿼리>에서 가장 큰 값이 나올 때 그걸 결과값으로 뱉어내는 형식인거야.

  • Chat GPT 문답


exists 연산자

exists(상관서브쿼리) : 상관서브쿼리의 반환된 행이 있다면 True, 없으면 False
  • 메뉴가 존재하는 카테고리만 조회하고자 한다.
  • tbl_category의 category code에 값이 없으면 False 반환해서 안 나옴

스칼라 서브쿼리

  • 벡터가 여러값이 나열된 거라면, 스칼라는 값 1개다.

인라인뷰(파생테이블)

FROM절에 서브쿼리를 사용한 것을 인라인뷰(INLINE-VIEW)라고 한다.
<VIEW란?>
-- 실제테이블을 주어진 뷰('보다'라는 의미를 가짐)를 통해 제한적으로 사용가능함.
-- 실제테이블에 근거한 논리적인 가상테이블(사용자에게 하나의 테이블처럼 사용가능)이다.
-- view 를 사용하면 복잡한 쿼리문을 간단하게 만듦으로써 가독성이 좋으므로 편리하게 쿼리문을 만들수 있다.
  • 별칭 필수
  • 인라인뷰에 작성되지 않은 컬럼은 select에 사용할 수 없다. 왜냐면 view로 한정해서 테이블을 보도록 했기 때문이다.
  • 별칭을 줬으면 이걸 컬럼명처럼 써야 함

Common Table Expression CTE

-- with 구문을 이용해서 inline view를 선언하고, 재사용한다.

  • 임의로 만들어진 테이블을 여러번 참조해야 할 때 유용하다.

0개의 댓글