CTE는 다른 SQL문(SELECT, INSERT, DELETE 등) 내에서 사용할 수 있는 임시 결과 세트이다.
조인이나 서브쿼리가 중첩되면 코드 길이도 길어지고 가독성이 떨어지기 때문에 CTE를 사용하여 임시 테이블을 생성하여 서브쿼리 결과를 재활용하며 WITH를 키워드로 사용한다.
-- CTE 문법
WITH cte_name (column_list) AS (
CTE_query_definition
)
statement;
[ VIEW ]
SQL에서 view란?
- view는 SELECT문과 같다고 생각하면 되며, 한 개 이상의 테이블을 사용하여 생성된 가상 테이블이다.
- 디스크에 물리적으로 저장되지 않기 때문에 가상 테이블이라고 불린다.
- view를 통해 제한적으로 데이터를 보이게 하는데 사용되며, 사용자는 주어진 view를 통해 기본 테이블을 제한적으로 사용한다.
- 데이터 딕셔너리(DB 운영에 필요한 스키마, 사용자, 권한 등의 정보가 있는 테이블)의 데이터를 조회하는 데에 주로 사용된다.(INSERT, DELETE, UPDATE도 가능하긴 함)
참고한 사이트
[ SQL의 조건문 ]
SQL문에서 조건문을 사용하기 위해서는 CASE WHEN ~ END구문을 사용하면 된다. 사용 방법은 다음과 같다.
CASE
WHEN 조건 1 THEN 결과 1
WHEN 조건 2 THEN 결과 2
...
(ELSE 결과 N)
ENDELSE는 쓰지 않아도 되지만 NULL 값이 있는 경우를 대비하여 어떤 것이라도 넣어주는 것이 좋다고 함
참고한 사이트
[PostgreSQL] 조건에 따라 다른값 보여주기 (CASE WHEN ~ ELSE ~ END)
-- 예제 1) film 테이블의 length컬럼값 변경한 임시 테이블 생성
WITH cte_film AS (
SELECT
film_id,
title,
(CASE
WHEN length < 30 THEN 'Short'
WHEN length < 90 THEN 'Medium'
ELSE 'Long'
END) AS length
FROM
film
)
SELECT *
FROM
cte_film
;
⇒ CTE를 선언하는 부분을 보면, film 테이블에서 film_id, title, length를 고르는데, length는 조건문을 활용하여 값을 변경한다. 그 결과로 나오는 테이블을 ‘cte_film’으로 이름을 지정함
<rental 테이블에서 staff_id 별 대여 횟수를 반환하는 CTE 생성
-- 예제 2) 테이블과의 조인
WITH cte_rental AS (
SELECT
staff_id,
COUNT(rental_id) AS rental_count
FROM
rental
GROUP BY
staff_id
)
SELECT *
FROM
cte_rental
;
<staff 테이블과 조인>
-- 예제 2) 테이블과의 조인
WITH cte_rental AS (
SELECT
staff_id,
COUNT(rental_id) AS rental_count
FROM
rental
GROUP BY
staff_id
)
SELECT
s.staff_id,
s.first_name,
s.last_name,
cr.rental_count
FROM
staff AS s
INNER JOIN cte_rental AS cr
on cr.staff_id = s.staff_id
;
[ window function ]
window function은 집계함수와 비슷하게 동작하는데, 집계함수는 결과로 하나의 행만 반환하는 반면, window function은 여러 개의 행을 반환하는 것이 큰 차이점이다. 사용법은 다음과 같다.
EX) 제품 품목에 따른 가격 평균 내기
AVG (price) OVER (
PARTITION BY group_name)⇒ 집계함수를 사용하고 뒤에 그룹화 할 기준 컬럼을 명시한다.
-- 예제 3) window fuction과 함께 사용하기
WITH cte_film AS (
SELECT
title,
rating,
length,
RANK() OVER(
PARTITION BY rating
ORDER BY length DESC) AS length_rank
FROM
film
)
SELECT *
FROM
cte_film
;
⇒ 그룹화 기준은 rating으로 하여 length의 순위를 매긴다.
recursive 쿼리는 조직구조, BOM(SAP 시스템에서 자재 품목을 기입해 놓은 리스트)와 같은 계층 구조에서 유용하게 사용한다. 사용 방법은 다음과 같다.
WITH RECURSIVE cte_name AS(
CTE_query_definition -- non-recursive
UNION [ALL]
CTE_query_definion -- recursive
)
SELECT *
FROM
cte_name;
[ recursive의 의미 ]
recursive는 ‘반복적으로 자기 자신을 활용하는 것’을 의미한다. 다음은 recursive의 의미를 이해하기 위한 파이썬 코드이다.
def recursive_function(num): print(num) recursive_function(num+10) recursive_function(1) >1 11 21 31 ...
recursive_function() 함수에는 숫자를 입력값으로 받아 출력하고 10을 더하여 함수 자기 자신을 다시 호출하는 방식으로 작동한다. recursive_function()처럼 함수 내부에서 자기 자신을 반복적으로 호출하는 구조를 recursive라고 한다.
recursive CTE가 동작하는 방법은 다음과 같다.
예제에서 사용할 employees 테이블은 아래와 같다. 20명의 직원 데이터가 있다. 직원 id가 있고, 직속 상사인 매니저의 id가 있다. 부하직원이 있는 직원 데이터를, 직원과 매니저 모두 반환해보자.
-- 예제 1) 특정 직원의 부하직원 검색
WITH RECURSIVE subordinates AS (
SELECT
employee_id,
manager_id,
full_name
FROM
employees
WHERE
employee_id = 2
UNION
SELECT
e.employee_id,
e.manager_id,
e.full_name
FROM
employees AS e
INNER JOIN subordinates AS s
ON s.employee_id = e.manager_id
)
SELECT *
FROM
subordinates;
↑ 최종 결과
recursive CTE의 동작을 하나하나 나눠보면 아래와 같이 구분동작으로 나눠질 수 있다.