만약 아래와 같이 주문 상품들 중 각 카테고리별로 주문 상태별 개수를 조회하는 쿼리가 있을 때,

SELECT
	p.category,
	COUNT(*) AS total_count,
	SUM(CASE WHEN status = 'COMPLETED' THEN 1 ELSE 0 END) AS completed_count,
	SUM(CASE WHEN status = 'SHIPPED' THEN 1 ELSE 0 END) AS shipped_count,
	SUM(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) AS pending_count
FROM
	orders o
JOIN
	products p ON o.product_id = p.product_id
GROUP BY
	p.category;

이 쿼리를 여러번 재사용하게 된다면 아래와 같은 문제가 있다.

그래서 이런 쿼리를 SELECT * FROM table; 처럼 간단한 조회 쿼리로 조회할 수 있도록 하는게 뷰의 역할이다.

뷰는 테이블처럼 쓰이지만 실제로는 데이터를 가지고 있지는 않고 저런 쿼리를 가지고 있어서

뷰를 통해 조회하면 그 뷰가 가지고 있는 쿼리를 실행하게 된다. 그래서 항상 최신 데이터를 조회할 수 있게 된다.

뷰를 사용하면 아래와 같은 장점이 있다.

-- 뷰 생성 : 테이블을 생성하듯이 생성하지만 마지막에 AS 키워드와 함께 실제 쿼리를 작성하면 된다.
-- 보통 뷰 이름앞에는 v, view 같은 접두어를 붙여서 테이블이 아닌 뷰 라는 것을 보여주는 경우가 많다.
CREATE VIEW v_category_order_status AS
SELECT
	p.category,
	COUNT(*) AS total_count,
	SUM(CASE WHEN status = 'COMPLETED' THEN 1 ELSE 0 END) AS completed_count,
	SUM(CASE WHEN status = 'SHIPPED' THEN 1 ELSE 0 END) AS shipped_count,
	SUM(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) AS pending_count
FROM
	orders o
JOIN
	products p ON o.product_id = p.product_id
GROUP BY
	p.category;

-- 뷰 삭제 : 테이블 등과 마찬가지로 IF EXISTS 조건으로 존재할때만 삭제할 수 있다.
DROP VIEW v_category_order_status;
DROP VIEW IF EXISTS v_category_order_status;

-- 뷰 조회 : 테이블을 조회하는 것과 동일하게 조회할 수 있다.
-- WHERE, ORDER BY 등도 똑같이 쓸 수 있고 결과로 나올 컬럼들을 안다면 컬럼도 지정할 수 있다.
-- 하지만 실제로는 아래 쿼리가 그대로 실행되는게 아니라 위에서 등록한 쿼리가 실행된다.
SELECT * FROM v_category_order_status;
SELECT total_count FROM v_category_order_status;
SELECT * FROM v_category_order_status WHERE category = 'book';

-- 뷰 수정 : ALTER 명령을 통해 수정하면 되고, 이렇게 수정된 쿼리가 기존 쿼리를 덮어씌운다.
ALTER VIEW v_category_order_status AS
SELECT
	p.category,
	COUNT(*) AS total_count
FROM
	orders o
JOIN
	products p ON o.product_id = p.product_id
GROUP BY
	p.category;

주의사항