SET Operator(SET 연산자, 집합연산자) - UNION, UNION ALL
------- ===== **** SET Operator(SET 연산자, 집합연산자) **** ===== -------
-- 종류 --
1. UNION
2. UNION ALL
3. INTERSECT
4. MINUS
--- 면접시 JOIN 과 UNION 의 차이점에 대해서 말해보기 ---
==> UNION 은 테이블(뷰)과 테이블(뷰)을 합쳐서 보여주는 것으로,
이것은 행(ROW)과 행(ROW)을 합친 결과를 보여주는 것이다.
공통이 존재하면 한번만 출력함
자동적으로 오름차순정렬됨
==> UNION ALL 은 중복제거X, 정렬X
A = { a, x, b, e, g }
- - ( - : 공통)
B = { c, d, a, b, y, k, m}
- -
A ∪ B = {a, b, c, d, e, g, k, m, x, y} ==> UNION
{a, b, c, d, e, g, k, m, x, y}
==> UNION ALL
{a, x, b, e, g, c, d, a, b, y, k, m}
A ∩ B = {a,b} ==> INTERSECT
{a,b}
A - B = {x,e,g} ==> MINUS
{x,e,g}
B - A = {c,d,y,k,m} ==> MINUS
{c,d,y,k,m}
-- tbl_panmae 테이블에서 2달 전에 해당하는 월(현재가 2022.07 이므로 2022.05)에 판매된 정보만 추출해서
-- tbl_panmae_202205 라는 테이블 생성하기
create table tbl_panmae_202205
as
select *
from tbl_panmae
where to_char( panmaedate, 'yyyy-mm' ) = to_char( add_months(sysdate, -2), 'yyyy-mm' );
-- Table TBL_PAMNAE_202205이(가) 생성되었습니다.
-- tbl_panmae_202205 테이블 생성되었는지 확인
select *
from tbl_panmae_202205;
-- tbl_panmae 테이블에 있는 5월 자료 삭제
delete from tbl_panmae
where to_char( panmaedate, 'yyyy-mm' ) = to_char( add_months(sysdate, -2), 'yyyy-mm' );
-- 5개 행 이(가) 삭제되었습니다.
commit;
-- tbl_panmae 테이블에서 1달 전에 해당하는 월(현재가 2022.07 이므로 2022.06)에 판매된 정보만 추출해서
-- tbl_panmae_202206 이라는 테이블로 생성하기
create table tbl_panmae_202206
as
select *
from tbl_panmae
where to_char( panmaedate, 'yyyy-mm' ) = to_char( add_months(sysdate, -1), 'yyyy-mm' );
-- Table TBL_PAMNAE_202206이(가) 생성되었습니다.
-- tbl_panmae_202206 테이블 생성되었는지 확인
select *
from tbl_panmae_202206;
-- tbl_panmae 테이블에 있는 6월 자료 삭제
delete from tbl_panmae
where to_char( panmaedate, 'yyyy-mm' ) = to_char( add_months(sysdate, -1), 'yyyy-mm' );
-- 4개 행 이(가) 삭제되었습니다.
commit;
--- *** 최근 3개월간 판매된 정보를 가지고 제품별 판매량의 합계를 추출하기 *** ---
select *
from tbl_panmae_202205; -- 2달 전 판매정보
select *
from tbl_panmae_202206; -- 1달 전 판매정보
select *
from tbl_panmae; -- 이번달 판매정보
UNION 하기
-- union을 하면 항상 첫번째 컬럼(지금은 panmaedate)을 기준으로 오름차순 정렬, 중복 행이 삭제되어 나온다.
select *
from tbl_panmae_202205 -- 2달 전 판매정보
UNION
select *
from tbl_panmae_202206 -- 1달 전 판매정보
UNION
select *
from tbl_panmae; -- 이번달 판매정보
UNION ALL 하기
-- UNIONALL 을 하면 정렬 없이 순서대로 행을 붙여서 보여줄 뿐이다.
select *
from tbl_panmae -- 2달 전 판매정보
UNION ALL
select *
from tbl_panmae_202205 -- 1달 전 판매정보
UNION ALL
select *
from tbl_panmae_202206; -- 이번달 판매정보
과자별 판매합계 추출하기
/*
----------------
제품명 판매합계
----------------
새우깡 76
허니버터칩 65
고구마깡 52
감자깡 50
*/
select jepumname as 제품명
, sum(panmaesu) as 판매합계
from
(
select *
from tbl_panmae_202205 -- 2달 전 판매정보
UNION
select *
from tbl_panmae_202206 -- 1달 전 판매정보
UNION
select *
from tbl_panmae
) V
group by jepumname
order by 2 desc;
또는
with V as
(
select *
from tbl_panmae_202205 -- 2달 전 판매정보
UNION
select *
from tbl_panmae_202206 -- 1달 전 판매정보
UNION
select *
from tbl_panmae
)
select jepumname as 제품명
, sum(panmaesu) as 판매합계
from V
group by jepumname
order by 2 desc;
-- 최근 3개월간 판매된 판매량의 총합계는 ?
-- 1. 틀린풀이 - UNION 을 사용하면 중복행이 삭제되어 나옴
select sum(panmaesu)
from
(
select panmaesu
from tbl_panmae_202205 -- 2달 전 판매정보
UNION
select panmaesu
from tbl_panmae_202206 -- 1달 전 판매정보
UNION
select panmaesu
from tbl_panmae
) V;
-- 98
-- 2. 올바른 풀이
select sum(panmaesu)
from
(
select panmaesu
from tbl_panmae_202205 -- 2달 전 판매정보
UNION ALL
select panmaesu
from tbl_panmae_202206 -- 1달 전 판매정보
UNION ALL
select panmaesu
from tbl_panmae
) V;
-- 243
---- *** [퀴즈] 최근 3개월간 판매되어진 정보를 가지고
-- 아래와 같이 제품명, 판매년월, 판매량의합계, 백분율(%) 을 추출하세요 *** ----
------------------------------------------------
제품명 판매년월 판매량의합계 백분율(%)
------------------------------------------------
감자깡 2022-05 20 8.2
감자깡 2022-06 15 6.2
감자깡 2022-07 15 6.2
감자깡 50 20.6
새우깡 2022-05 38 15.6
새우깡 2022-06 8 3.3
새우깡 2022-07 30 12.3
새우깡 76 31.3
..... ....... ... ....
전체 243 100.0
------------------------------------------------
-- [첫번째 방법]
select decode( grouping( jepumname ), 0, jepumname, '전체') as 제품명
, decode( grouping( to_char(panmaedate, 'yyyy-mm') ), 0, to_char(panmaedate, 'yyyy-mm'), ' ' ) as 판매연월
, sum(panmaesu) as 판매량의합계
, to_char( round( sum(panmaesu)/(select sum(panmaesu)
from
(
select *
from tbl_panmae_202205
UNION ALL
select *
from tbl_panmae_202206
UNION ALL
select *
from tbl_panmae
)
)*100, 1 ), '999.0' ) as "백분율(%)"
from
(
select *
from tbl_panmae_202205
UNION
select *
from tbl_panmae_202206
UNION
select *
from tbl_panmae
) V
group by grouping sets( (jepumname, to_char(panmaedate, 'yyyy-mm') ), (jepumname), () );
-- 또는
-- group by rollup( jepumname, to_char(panmaedate, 'yyyy-mm') ) : 뒤에서부터 없어짐
-- [두번째 방법]
with V as
(
select *
from tbl_panmae_202205
UNION
select *
from tbl_panmae_202206
UNION
select *
from tbl_panmae
)
select decode( grouping( jepumname ), 0, jepumname, '전체') as 제품명
, decode( grouping( to_char(panmaedate, 'yyyy-mm') ), 0, to_char(panmaedate, 'yyyy-mm'), ' ' ) as 판매연월
, sum(panmaesu) as 판매량의합계
, to_char( round( sum(panmaesu)/( select sum(panmaesu) from V ) * 100, 1 ), '999.0' ) as "백분율(%)"
from V
group by grouping sets( (jepumname, to_char(panmaedate, 'yyyy-mm') ), (jepumname), () );