se0ehe 2024. 7. 3. 20:01

 

2024.07.03

 

✳️ WITH 절

하나의 서브쿼리 또는 임시 테이블처럼 활용할 수 있는 기능

- 기본 구조

WITH (테이블명) AS
                  (
                  WITH절로 저장하고 싶은 쿼리문
                  )
                  
SELECT * FROM (WITH절로 저장한 테이블명)
;



⭐ WITH 절 장점

1. 코드의 가독성을 높임
서브쿼리가 여러 번 사용되면 자연스럽게 쿼리가 길어지고 가독성이 떨어진다.
with 절을 이용하면 가독성 문제를 해소할 수 있다.
(개인적으로 작성하는 순서가 밑에서 위로 쓰는 서브쿼리 대신에 위에서 아래로 쓰는 순서라 작성할 때도 편한 것 같다.)

with (테이블 명_1) as (
 
		with절로 저장하고 싶은 SQL 쿼리문 1
    
)
 
, (테이블 명_2) as (
 
		with절로 저장하고 싶은 SQL 쿼리문 2
    
)
 
, (테이블 명_3) as (
 
		with절로 저장하고 싶은 SQL 쿼리문 3
    
)
 
select * 
 
from (with절로 저장한 테이블명_1)
	join (with절로 저장한 테이블명_2)
    left join (with절로 저장한 테이블명_3) 
;


2. SQL 성능 개선
 with 절의 동작 방식 때문에 발생하는 장점이다.


⭐ WITH 절 동작 방식

1️⃣ inline view
임시 테이블을 생성하지 않고 쿼리 그 자체로 저장해두는 방식
이 방식은 with 절이 본절에서 1번 사용될 때 활용되는 방식으로 서브쿼리와 다를 것 없는 성능을 보여준다.

WITH total_price AS (
                     SELECT custmoer_id
                          , SUM(price*discount_rate) as A
                          From receipts
                          GROUP BY 1
                    )
SELECT A.custmoer_id, price, total_price
FROM receipts A 
     JOIN total_price B 
     ON A.custmoer_id=B.custmoer_id 
;


2️⃣ Materialize
임시 테이블을 생성하여 쿼리의 결과값을 저장하고 반복해서 재사용하는 방식
with 절로 정의된 테이블이 2번 이상 사용될 때 활용된다.

SELECT '001&003' AS co_cd
      , sum(seq*price) AS tot_amt
FROM receipts AS A JOIN companies AS B ON A.cust_id = B.district
WHERE co_cd IN ('001', '003')
GROUP BY 1
 
UNION ALL
 
SELECT '002&004' AS co_cd, SUM(seq*price) AS tot_amt
FROM receipts AS A JOIN companies AS B ON A.cust_id = B.district
WHERE co_cd IN ('002', '004')
GROUP BY 1
;

 

WITH join_table AS (
	             SELECT A.*
                    , seq*price AS tot_amt
                    , B.co_cd
	             FROM receipts A JOIN companies B ON A.cust_id = B.district
                    )
 
SELECT '001&003' AS co_cd
      , SUM(tot_amt) AS tot_amt
FROM join_table
WHERE co_cd IN ('001', '003')
GROUP BY 1
 
UNION ALL
 
SELECT '002&004' AS co_cd
      , sum(tot_amt) AS tot_amt
FROM join_table
WHERE co_cd in ('002', '004')
GROUP BY 1
;


with절을 사용한 경우 join을 시켜둔 테이블의 결과값을 사용하게 되어 실행 횟수를 2번에서 1번으로 줄일 수 있습니다.

 

참고자료

https://schatz37.tistory.com/46

 

[SQL] with 절을 효율적으로 사용하기

요즘 회사에서 '어떻게 하면 보다 효율적인 sql을 작성할 수 있을까?' 라는 부분에 굉장히 많이 고민하고 있는데요. 이번 포스팅에서는 공부가 필요하다고 생각되는 with절에 대해서 포스팅하려

schatz37.tistory.com