반응형



안녕하세요~


오늘은 두 집합을 연결하는 또 다른 연산자 UNION에 대해 알아보겠습니다!


UNION은 위의 사진처럼 TABLES의 행(ROW)을 위 아래로 결합하는 것입니다.


더 자세히 알아볼까요?


집합 연산자란?


두 집합 사이의 합집합 , 교집합, 차집합을 출력하는 연산자 입니다.




그렇다면 JOIN과는 어떠한 차이점이 있을까요?



JOIN            VS           UNION



JOIN절은 위와같이 옆으로! COLUMN이 추가되며 합쳐지는 형태를 갖습니다.


반면에


UNION절은 위 - 아래로 하나의 COLUMN에 ROW가 추가되는 형태를 갖습니다.


(조인을 더 알고 싶다면 여기로)



먼저, UNION 절의 종류에 대해 알아봅시다!




      - UNION ALL: 두 집합의 합집합을 출력하는 연산자

  

      - UNION: 두 집합의 합집합을 출력하는 연산자.

                    (단 중복을 제거하여 반환)


      - INTEREST: 교집합을 출력하는 연산자

                       ( 양쪽 쿼리에 공통되는 행을 반환 )


      - MINUS: 두 집합 사이의 차집합을 출력하는 연산자로

                     첫번째 쿼리에 의해 선택되지만

                     두번째 쿼리 결과 집합에는 없는 모든 행을 반환



* 참고: 위에서 의미하는 집합이란 결과 데이터를 의미합니다.




예제를 통해 UNION절의 사용방법에 대해 알아보겠습니다.


[ 고객A 테이블 ]


고객이름

 나이

  주소 

 총구매액

 추천인

 A

 24

 서울

 30000

 null

 B

 29

 서울

 10000

 A

 C

 26

 파주

 25000

 A

 D

 27

 제주

 1000

 B




예제1. UNION ALL 과 UNION의 차이를 확인해보죠!



    

    SQL1> SELECT 고객이름

                         FROM 고객

              UNION ALL

              SELECT 고객이름

                         FROM 고객; 

 

    SQL2> SELECT 고객이름

                         FROM 고객

              UNION

              SELECT 고객이름

                         FROM 고객; 





SQL1 UNION ALL 결과

 고객이름

 A

 B

 C

 D

 A

 B

 C

 D



SQL2 UNION 결과


 고객이름

 A

 B

 C

 D



참고:


INTEREST 와 MINUS 연산자의 경우

위의 UNION ALL/ UNION 자리에 입력하여 결과를 확인하면

쉽게 이해하실 수 있을 것 같아서 PASS!



집합연산자 사용시 주의사항


1. 집합 연산자 위-아래의 쿼리문의 컬럼의 갯수와 데이터 타입이 동일해야한다.


2. ORDER BY절은 맨 아래 쿼리에만 사용할 수 있으며

ORDER BY절을 사용하려면 쿼리문들의 컬럼명과 데이터 타입이 모두 동일해야합니다!

( 특히 SELECT 문에서 NULL값을 두개 이상 사용할 경우!

ALIAS로 COLUMN명을 동일하게 만들어준다!! )





두번째! UNION 절과 함께 알아두면 좋은~

레포팅 함수에 대해 알려드릴께요!



<레포팅함수 종류>


 

       - ROLLUP


       - CUBE


       - GROUPING SETS


       - GROUPING (여기서 다루지 않음)

                        : (리얼) Null ( --> 0)

                           grouping되는 결과를 보기위해

                          어쩔수 없이 null 출력되는 데이터( --> 1 )를

                   구분해 주기 위해서 사용하는 함수





예제2: 주소, 나이, 주소별 & 나이별 고객의 총 구매액을 구하고

마지막에 전체 고객의 총 구매액을 추가해주세요



        

     -- UNION 절


      SQL3> SELECT 주소, 나이, SUM(총구매액)

                            FROM 고객

                            GROUP BY 주소, 나이

                UNION

                SELECT NULL  주소, NULL 나이, SUM(총구매액)

                            FROM 고객

                ORDER BY 주소 ASC;


     -- ROLLUP절

 

     SQL4> SELECT 주소, 나이, SUM(총구매액)

                           FROM 고객

                           GROUP BY ROLLUP ( (주소, 나이) );




SQL3 & SQL4의 결과


주소

 나이

 SUM(총구매액)

 서울

 24

 30000

 서울

 29

 10000

 제주

 27

 1000

 파주

 26

 25000

 null

 null

 30000+10000+1000+25000



위와 같이 두개의 SQL문이 실행되야하는 UNION절

하나의 SQL문이 실행되는 ROLLUP으로 대신 사용하면

속도가 보다 빨라지기 때문에 성능이 더 좋다고 할 수 있겠죠?



위의 SQL2문에서 ROLLUP함수에 ( ( ) ) 두 개의 괄호가 있는 것을 눈치 채셨나요?


만약 괄호를 ( ) 한 개만 사용한다면 어떻게 될까요?



     -- ROLLUP절

 

     SQL5> SELECT 주소, 나이, SUM(총구매액)

                         FROM 고객

                         GROUP BY ROLLUP ( 주소, 나이 );



SQL5 결과


주소 

 나이

 SUM(총구매액)

 서울

 24

 30000

 서울

 29

 10000

 서울                  

 null                    

 30000 + 10000                

 제주

 27

 1000

 제주                  

 null                    

 1000                             

 파주

 26

 25000

 파주                  

 null                    

 25000                           

 null

 null

 30000+10000+1000+25000



위의 색칠되어있는 부분이 추가된 것을 볼 수 있습니다.


이것은 ROLLUP의 특징인데요



'SQL5의 실행 순서'를 보면


1. (주소, 나이)로 그룹핑하여 총합을 구한다


2. (주소)로 그룹핑하여 총합을 구한다


3. (체) 총합을 구한다



위의 SQL4, SQL5결과를 각각 GROUP SETS로 실행시켜봅시다!


 

       -- SQL4를 GROUP SETS로       


      SQL6> SELECT 주소, 나이, SUM(총구매액)

                          FROM 고객

                          GROUP BY GROUP SETS ( (주소, 나이),

                                                                        ( ) );

 

        -- SQL5를 GROUP SETS로      

       

      SQL7> SELECT 주소, 나이, SUM(총구매액)

                         FROM 고객

                         GROUP BY GROUP SETS ( (주소, 나이),

                                                                    (주소),

                                                                      ( ) );




따라서


GROUP SETS는 ROLLUP보다 GROUPING된 결과를 더 잘 예상할 수 있어 작성하기도 편하답니다! 



참고:


 CUBE는 간단히 ROLLUP의 반대라고 생각하면 됩니다!


예제2와 달리 총구매액이 맨 위로 출력됩니다!





오늘은 여기까지!


내일은 서브쿼리로 돌아올겠습니다~



(오늘이 금요일이 아니라니..)

반응형
반응형


오늘은~ JOIN절 2탄!


1탄은 ORACLE | JOIN을 사용하는 오라클만의 방법! 에 있습니다~



JOIN은 기본적으로 위의 퍼즐같이 두개 이상의 테이블의 컬럼을 합쳐서

하나의 테이블처럼 사용하는 방법입니다.


그럼~ 차근차근 따라가 볼까요?



오라클 조인 문법과 1999 ANSI 조인 문법을 모두 이용하여 문제를 풀어보겠습니다.



[ 고객 테이블 ]


고객이름

 나이

  주소 

 총구매액

 추천인

 A

 24

 서울

 30000

 null

 B

 29

 서울

 10000

 A

 C

 26

 파주

 25000

 A

 D

 27

 제주

 1000

 B



[ 주소 테이블 ]


주소 

 관할부서

 서울

 한국 A

 일산

 한국 B

 파주

 한국 C

 제주

 한국 D



[ 등급 테이블 ]


고객등급 

 최소구매액

 최대구매액

 1

 0

 9999

 2

 10000

 19999

 3

 20000

 30000




문제1. 고객 이름, 관할부서, 고객등급을 출력하시오





결과


 고객이름

 관할부서

 고객등급

 A

 한국 A

 3

 B

 한국 A

 2

 C

 한국 C

 3

 D

 한국 D

 1




중요!


TABLE이 3개일 경우 연결고리는 2 ( = 3 - 1) 개 입니다.



오라클 조인 문법에서 JOIN절의 WHERE절은 '조인 조건'으로 사용됩니다.



여기서 주의해야할 점은 1999 ANSI문법의 경우 양쪽에 연결고리가 있는 테이블명을 먼저 작성해야합니다.


또한, 1999 ANSI문법의 경우 오라클 문법과 달리 WHERE절은 그저 '검색 조건' 입니다.


따라서 JOIN절에서 조인 조건을 주기 위해서는 ON절을 사용하여 '조인 조건'을 줄 수 있습니다.




오라클 Database에서는 어떠한 문법을 사용하여도 문제가 없습니다.


하지만,


1999 ANSI 문법의 경우 '조인 조건' ON과 '검색 조건' WHERE이 별개로 구분되어 있기 때문에

보다 가독성이 좋다고 하네요~




추가) using절을 사용한 조인과 natural join



위의 정답 문법을 각각 using 절과 natural join으로 바꾼 SQL문을 먼저 확인하시죠.



 

       SQL> SELECT c.고객이름, a.관할부서, g.고객등급

FROM 고객 c JOIN 주소 a

USING ( 주소 )  

JOIN 등급 g

ON ( c.총구매액 BETWEEN 최소구매액 AND 최대구매액 );





 

       SQL> SELECT c.고객이름, a.관할부서, g.고객등급

FROM 고객 c NATURAL JOIN 주소 a

 JOIN 등급 g

ON ( c.총구매액 BETWEEN 최소구매액 AND 최대구매액 );





먼저 using절에서 주의사항이 있습니다.


 using절에서는 테이블 별칭 즉, c.주소 or a.주소를 사용하지 않습니다.



natural join의 경우 오라클이 알아서 고객 table과 주소 table의 공통의 컬럼(column)을 찾아서 조인을 합니다!


natural join에서 주의할 점은

공통 컬럼이 없는 경우 or data type이 다른 경우 오류가 발생한다는 것입니다.


(참고: data type을 모른다면 여기!)




오늘은 여기까지


내일은 집합 연산자 union으로 돌아올겠습니다!



이 글이 도움되셨다면 아래 공감 꾹~ 



반응형
반응형


안녕하세요!


오늘은 오라클에서 테이블을 JOIN하는 방법에 대해 알아보겠습니다.




JOIN이란?


여러 개의 테이블의 데이터를 하나의 결과(테이블)로 모아서 출력하는 SQL문법입니다.



조인의 종류는 크게 오라클 조인 문법과 1999 ANSI 조인 문법으로 나눌 수 있습니다.


1999 ANSI 조인은 많은 관계형 데이터베이스에서 공통적으로 사용하는 SQL문입니다. 프로그래머를 꿈꾸는 많은 분들이 사용하는 MySQL에서는 이 방법을 사용하고 있습니다.


반면에 오라클 조인문법은 오라클에서 독자적으로 만들어 JOIN SQL문법을 사용하였습니다.


하지만 현재, 오라클에서는 독자적인 오라클 조인문법과 1999 ANSI 조인문법을 모두 이용하여 테이블 JOIN을 할 수 있답니다.



1. 오라클 조인 문법


  

  (1) EQUI JOIN


  (2) NON EQUI JOIN


  (3) OUTER JOIN


  (4) SELF JOIN




2. 1999 ANSI 조인 문법



  (1) FULL OUTER JOIN


  (2) RIGHT/LEFT OUTER JOIN


  (3) ON절을 사용한 JOIN


  (4) USING절을 사용한 JOIN


  (5) NATURAL JOIN


  (6) CROSS JOIN





앞으로 아래의 테이블을 활용하겠습니다.

우선 테이블의 관계를 살짝 확인하고 따라 오세요!



[ 고객 테이블 ]


고객이름

 나이

  주소 

 총구매액

 추천인

 A

 24

 서울

 30000

 null

 B

 29

 일산

 10000

 A

 C

 26

 파주

 25000

 A

 D

 27

 

 0

 B



[ 주소 테이블 ]


주소 

 관할부서

 서울

 한국 A

 일산

 한국 B

 파주

 한국 C

 제주

 한국 D



[ 등급 테이블 ]


고객등급 

 최소구매액

 최대구매액

 1

 0

 9999

 2

 10000

 19999

 3

 20000

 30000





  EQUI JOINNON EQUI JOIN



EQUI JOIN 예시


고객이름, 나이, 주소, 관할부서를 알고 싶어요!


 

 SQL> SELECT c.고객이름, c.나이, c.주소, a.관할부서

                  FROM 고객 c, 주소 a

                  WHERE c.주소 = a.주소 ;




결과:


고객이름 

 나이

 주소

 관할부서

 A

 24

 서울

 한국 A

 B

 29

 일산

 한국 B

 C

 26

 파주

 한국 C




NON EQUI JOIN 예시


고객이름, 나이, 고객등급을 알고 싶어요!



 

 SQL> SELECT c.고객이름, c.나이, g.고객등급

             FROM 고객 c, 등급 g

             WHERE c.총구매액 

                       BETWEEN g.최소구매액 AND g.최대구매액 ;




결과:


고객이름 

 나이

 고객등급

 A

 24

 3

 B

 29

 2

 C

 26

 3

 D

 27

 1



위의 SQL문의 차이를 발견하셨나요?


문제1. EQUL JOIN과 NON EQUI JOIN의 차이는 무엇일까요?




또한,


각각의 예시에서 알 수 있듯이 JOIN을 하기위해서는 WHERE절을 통해 연관 데이터로 조인 조건을 줍니다.


이때 WHERE절은 검색조건이 아닌 '조인 조건'입니다.



추가 문제: 만약, 조인 조건이 없을 경우에는 어떻게 될까요?






  OUTER JOIN


OUTER JOIN은 


EQUI JOIN으로는 볼 수 없는 결과를 볼 때 사용하는 조인입니다.

(EQUI JOIN으로 조인되지 않은 데이터를 볼 때 사용하는 방법입니다.)



문제2. 위의 EQUL JOIN 예시의 결과를 보면 주소가 없는 고객 D는 출력되지 않았습니다.

과연, JOIN시에 고객D를 출력하고 싶으면 어떻게 해야할까요?





이때 사용하는 것이 바로 OUTER JOIN SIGN입니다.


ORACLE에서는 ( + ) 를 이용하여 OUTER JOIN이 가능합니다.


결과:


고객이름 

 나이

 주소

  관할부서

 A

 24

 서울

 한국 A

 B

 29

 일산

 한국 B

 C

 26

 파주

 한국 C

 D

 27

 null

 null



* 참고: 1999 ANSI JOIN절에서는 LEFT / RIGHT OUTER JOIN절로 위와 같은 결과를 출력할 수 있습니다.




  SELF JOIN


문제3. 고객이름, 추천인 이름을 알고 싶습니다.





위의 문제의 경우 SELF JOIN을 이용하여 결과를 출력합니다.


SELF JOIN은 자기 자신의 테이블과 조인하는 문법으로


FROM문에서 테이블 별칭을 사용하여 마치 두개의 테이블이 존재하는 것처럼 JOIN문을 작성하면 됩니다.




여기까지!


어렵지만 중요한 JOIN문에 관한 문법을 알아봤습니다!


특히 MySQL을 사용하던 사람으로서 보다 편리한듯, 불편한듯 신기한 부분이 많았던것 같아요!


다들 참고해서 더 나은 빅데이터 분석가가 되어봐요~



여기서 다루지 못한 1999 ANSI 조인문은 다음 포스팅에서 확인하실 수 있습니다!


이 글이 도움되셨다면 아래 공감 꾹~ 



반응형
반응형


안녕하세요!


오늘은 SQL 분석함수에 대해 다뤄보도록 하겠습니다!



분석함수란,


기본 함수로는 구현하기 어려운 데이터의 분석을 쉽게 도와주는 함수입니다.



출처: https://www.mbs.ac.uk



1. RANK 함수


: data 의 순위를 출력하는 함수입니다.


순위 기준 값이 같은 행은 순위도 동일하게 결정됩니다.


순위가 동일한 행의 수를 동일한 순위에 추가하여 다음 순위를 계산하기 때문에 순위가 연속된 수가 아닐 수도 있습니다.


예를 들어, 두 행의 순위가 1로 결정되면 다음 순위는 3입니다.


구문


RANK ( ) OVER

 (

 [ PARTITION BY expr_list ]

 [ ORDER BY order_list ]

 ) 



( ) 


함수에 인수가 없지만 빈 괄호가 필요합니다.


OVER


이후 절에 대하여 rank를 확장한다는 의미가 있습니다.


PARTITION BY expr_list


(선택) PARTITION 즉, 분할을 한다는 의미의 조건절 입니다.

RANK의 조건을 정의하는 하나 이상의 표현식입니다.


ORDER BY order_list 


(선택) 순위 값의 기준이 되는 열을 정의합니다. PARTITION BY를 지정하지 않으면 ORDER BY가 전체 테이블을 사용합니다. 즉, ORDER BY가 생략되면 모든 행의 반환 값은 1입니다.


(ORDER BY에서 고유한 순서를 지정하지 않으면 행의 순서는 비확정적입니다.)



반환유형


INTEGER (즉, RANK에 해당하는 숫자)


구 문 출 처: AWS  



활용하기


아래와 같은 COLUMN을 갖고 있는 EMP라는 테이블이 있다고 가정합시다.


EMPNO

ENAME

JOB

SAL

DEPTNO

 

참고: 테이블 스키마를 확인하고 싶을 때

--> SQL>  desc 테이블명;



이 테이블에 대해 아래의 쿼리를 실행해 봅니다.


  SQL> SELECT * FROM EMP;



<결과>


EMPNO

ENAME

JOB

SAL

DEPTNO

 1

 A

 SALESMAN

 1250

 10

 2

 B

 SALESMAN

 1600

 10

 3

 C

 MANAGER

 3000

 20

 4

 D

 CLERK

 1100

 20

 5

 E

 ANALYST

 3000

 30

 6

 F

 ANALYST

 3000

 30

 7

 G

 CLERK

 1300

 30

 8

 H

 MANAGER

 2450

 10

 9

 I

 SALESMAN

 1500

 10



문제1. 이름, 연봉, 순위를 출력하는데

순위는 연봉이 높은 순서로 출력되게 하시오.




추가)


DENSE_RANK 함수와의 비교:


한가지 측면에서 RANK와 DENSE_RANK가 다릅니다.


DENSE_RANK에서는 2개 이상의 행에서 순위가 동일하면 순위 값의 순서에도 빈자리가 없습니다.


예를 들어 두 행의 순위가 1로 결정되면 다음 순위는 2입니다.


(rank의 경우 두 행의 순위가 1로 결정되면 다음 순위는 3입니다.)





2. PIVOT 함수


: 세로(ROW)로 출력되는 결과를 가로(COLUMN)로 출력하는 함수입니다.



관계형 테이블은 다음과 같이 행과 열로 구성됩니다.


EMPNO

ENAME

JOB

SAL

DEPTNO

 1

 A

 SALESMAN

 1250

 10

 2

 B

 SALESMAN

 1600

 10

 3

 C

 MANAGER

 3000

 20

 4

 D

 CLERK

 1100

 20

 5

 E

 ANALYST

 3000

 30

 6

 F

 ANALYST

 3000

 30

 7

 G

 CLERK

 1300

 30

 8

 H

 MANAGER

 2450

 10

 9

 I

 SALESMAN

 1500

 10



문제2. 우선 부서별로 총 월급의 합을 출력해보겠습니다.


 SQL> SELECT DEPTNO, sum(SAL)

              FROM EMP

              GROUP BY DEPTNO;



<결과>


DEPTNO 

SUM(SAL) 

 10

 1250 +  1600 + 2450 + 1500

 20

 3000 + 1100

 30

 3000 + 3000 + 1300



문제3. 과연 이 테이블을 아래와 같이 만드는 방법이 있을까요?


10 

20 

30 

1250 +  1600

   + 2450 + 1500

3000 + 1100

 3000 + 3000 + 1300





참고)


 PIVOT함수를 이용할 때, FROM절에서 SELECT문을 서브쿼리로 이용하여야합니다.

 또한 SELECT 서브쿼리문에서는 결과를 보기위해 필요한 컬럼만을 선별합니다.



원리 설명



추가)


UNPIVOT:


가로(COLUMN)을 세로(ROW)로 출력하는 함수



아래의 간단한 예시를 통해 이해해보도록 합시다!



[EMP2 테이블]


DEPTNO 

A

B

C

D

E

F

G

H

I

10

1250

1600

 

 

 

 

 

2450

1500

20

 

 

3000

1100

 

 

 

 

 

30

 

 

 

 

3000

3000

1300

 

 



문제4. ENAME, DEPTNO, SAL COLUMN으로 테이블을 출력하세요




결과


DEPTNO 

ENAME

SAL

10

A

1250

10

B

1600

10

H

2450

10

I

1500

20

C

3000

20

D

1100

30

E

3000

30

F

3000

30

G

1300




그렇다면 PIVOT 함수는 왜 필요할까요?


임의의 관계현 테이블에 대한 크로스탭 리포트를 생성할 수 있습니다.


UNPIVOT 연산자를 사용하면 임의의 크로스탭 리포트를 정규 관계형 테이블로 변환하는 것이 가능합니다.


참고) PIVOT은 출력결과를 일반 텍스트 또는 XML 포맷으로 반환합니다.



오늘은 유독 글쓰기가 힘드네요


월요병인가 봅니다..


내일은 보다 날씨도, 뇌도 상쾌한 하루가 되길 기대해봅니다!



이 글이 도움되셨다면 아래 공감 꾹~ 






반응형

+ Recent posts