수업/수업정리
2024-03-21-오전오후:DDL실습8:VIEW, CTE(WITH)
Dev.chandel
2024. 3. 21. 17:27
/*
1. View
(1) 정의
-사용자의 접근이 허용된 자료를 제한적으로 보여주기 위해 하나 이상의 기본 테이블로부터 만들어진 가상의 테이블
(2) 장점
-보안 강화
-간단한 SQL문을 사용 가능
-사용자에게 필요한 내용만 보여줄 수 있다.
(3) 특징
-이름을 가지는 가상의 테이블
-사용자 입장에서는 테이블과 동일하게 사용 가능
-ALTER 구문을 사용할 수 없다.
(4) 종류
-단순 뷰 : 하나의 테이블과 연결된 뷰
-복합 뷰 : 2개 이상의 테이블과 연관된 뷰
(5) 구문
CREATE VIEW v_뷰이름
AS
SELECT문
주의 : 뷰가 테이블 X SQL문을 저장한다.
SQL문을 만들어서 실행해보고(테스트), 그걸 뷰로 제작
*/
-- 1. city table에서 지역구가 England에 속한 도시 이름과 국가 코드를 조회하는 뷰를 생성
-- 그리고, 뷰 호출 시, 도시 이름만 조회
CREATE VIEW v_england
AS
SELECT
c.Name,
c.CountryCode
FROM
city AS c
WHERE
c.District = 'England';
SELECT
ve.Name AS '도시 이름'
FROM
v_england AS ve;
-- 2. 회원 별 구매 이력 중, 구매 금액이 가장 높은 금액의 상품의 이름과 가격, 회원의 이메일을 조회하는 뷰
-- 생성 뷰 조회시 구매자 아이디, 제품명, 가격 조회
CREATE VIEW v_highprice
AS
SELECT
g.g_price,
g.g_name,
m.m_email,
m.m_id
FROM
tb_order AS o
INNER Join
tb_goods AS g
on
g.g_code = o.o_g_code
INNER join
tb_member AS m
on
m.m_id=o.o_id
GROUP BY
m.m_id
HAVING
MAX(g.g_price);
SELECT
vh.m_id AS '구매자 아이디',
vh.g_name AS '제품명',
vh.g_price AS '가격'
FROM
v_highprice AS vh;
/*
2. CTE(common table expression, 공통 테이블 식)
-mysql 8버전 이상에서 사용 가능
(1) 정의
-임시로 쿼리 조회 결과를 저장하고 사용.
3. WITH절
(1) 정의
-CTE 사용하기 위한 구문
-SQL 표준(ANSI-SQL99)
-세미콜론(;)사용하면 안됨!
(2) 특징
-복잡한 쿼리 부분을 조각해서 나눠 가독성 향상
(3) 구문
-- 방법1
WITH cte_이름(열_이름1, 열_이름2...)
AS
(
SELECT
조회할_열1,
조회할_열2
FROM
R
)
-- 방법2
WITH
cte1 AS(SELECT 조회할_열1, 조회할_열2 FROM R1),
cte2 AS(SELECT 조회할_열3, 조회할_열4 FROM R2),
*/
-- 예시1번
WITH cte_pop_usa(cityName,cityDist,cityPop)
AS
(
select
c.Name,
c.District,
c.Population
from
city AS c
where
c.CountryCode = 'usa'
)
SELECT
*
FROM
cte_pop_usa
ORDER BY cityPop DESC;
-- 예시2번
WITH cte_pop_usa AS(SELECT * FROM city AS c WHERE c.CountryCode = 'usa')
SELECT
*
FROM
cte_pop_usa
ORDER BY c.CountryCode DESC;
-- 3. 가장 인구수가 많은 도시의 이름과 인구수,
-- 가장 인구수가 적은 도시 이름과 인구수를 조회하는 cte를 만들고,
-- 가장 많은 인구수의 도시이름과 인구수, 가장 적은 인구수의 도시이름과 인구수 조회
WITH cte_cityPop
AS
(
SELECT
MAX(c.Population) AS max_pop,
MIN(c.Population) AS min_pop
FROM
city AS c
)
SELECT
c.Name,
c.Population
FROM
city AS c
INNER JOIN
cte_cityPop AS cp
WHERE
c.Population=cp.max_pop
or
c.Population=cp.min_pop;
/*
GROUP_CONCAT
(1) 정의
-서로 다른 결과를 한 줄로 합쳐서 보여줄때 사용
(2) 구문
SELECT
type,
GROUP_CONCAT(DISTINCT name)
FROM
R
GROUP_BY type;
(3) 구분자 변경
GROUP_CONCAT(컬럼_이름 SEPARATOR '&') <-- &로 구분지음
*/
-- 4. CTE를 사용하여 구매자 별 구매 이력 중, 구매 상품 별 구매 수량이 20개 이상인 상품의 목록을 추출
-- 조회시 GROUP_CONCAT 사용하여 구매자와 구매리스트를 조회
WITH cte_order
AS
(
SELECT
o.o_id AS oid,
g.g_name AS gname
FROM
tb_order AS o
INNER JOIN
tb_goods AS g
on
o.o_g_code=g.g_code
GROUP by
o.o_id, g.g_code
HAVING SUM(o.o_amount) >= 20
)
SELECT
m.m_name AS '구매자',
GROUP_CONCAT(DISTINCT co.gname SEPARATOR '&') AS '구매리스트'
FROM
tb_member AS m
INNER JOIN
cte_order AS co
on
m.m_id = co.oid
GROUP BY m.m_name;
WITH cte_swithc
AS
(
SELECT
g.g_seller_id AS sid,
o.o_id AS oid
FROM
tb_goods AS g
INNER JOIN
tb_order AS o
on
g.g_code = o.o_g_code
)
SELECT
cte_sc.sid AS '판매자 아이디',
m.m_name AS '판매자의 이름',
GROUP_CONCAT(DISTINCT cte_sc.oid SEPARATOR ', ') AS '구매자 아이디'
FROM
tb_member AS m
INNER JOIN
cte_swithc AS cte_sc
on
m.m_id = cte_sc.sid
GROUP BY cte_sc.sid;