SQL

SET Operator(SET 연산자, 집합연산자) - UNION, UNION ALL

에어팟맥스 2022. 7. 11. 17:38

------- ===== **** 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), () );