반응형


안녕하세요~


오늘은 다중 INSERT문에 대해 알아보겠습니다.


사용법을 알아보기 전 의미를 알아볼까요?


다중 INSERT문이란?


데이터를 입력할 때 여러 개의 테이블에

동시에 데이터를 입력할 수 있게 해주는 INSERT문입니다.



다중 테이블 INSERT 구문:



         INSERT [ALL | FIRST]

               [WHEN condition THEN] 

                        [insert_into_clause values_clause]

               [ELSE] [insert_into_clause values_clause]

        (subquery)



우선 공통적으로 INSERT ... SELECT 문을 사용하여 행을

단일 DML 문의 일부로 다중 테이블에 삽입합니다.



다중 INSERT 문의 종류는 4가지로 나눌 수 있습니다.



      1. 무조건 ALL INSERT 문: ALL into_clause


      2. 조건부 ALL INSERT 문: conditional_insert_clase


      3. 조건부 FIRST INSERT 문: FIRST conditional_insert_clase


      4. PIVOTING INSERT 문

           (pivot함수를 사용하지 않고 pivot의 효과를 냄)

 



예제를 통해 알아봅시다!


우선 이미 고객 테이블이 존재한다고 가정합시다.


[ 고객 테이블 ]


고객이름

 나이

  주소 

 총구매액

 추천인

 A

 24

 서울

 30000

 null

 B

 29

 서울

 10000

 A

 C

 26

 파주

 25000

 A

 D

 31

 제주

 1000

 B

 E

 19

 null

 15000 C



예제1.

주소가 서울인 사람과 파주인 사람, 제주인 사람을

각각 고객_서울, 고객_파주, 고객_제주 테이블에 한번에 입력하세요.

(단, 고객_서울, 고객_파주, 고객_제주 테이블은 이미 존재한다고 가정)



앞서 사용한 SQL문이 바로 조건부 ALL INSERT 문입니다.




예제2.

우리의 타겟 고객은 20-30대이다.


나이가 30 이상 39 이하인 고객은 고객_30 테이블에,

나이가 20 이상 29 이하인 고객은 고객_20 테이블에,

그외의 고객은 고객_예외 테이블에 한번에 입력하세요.

(여기서도 이미 각각의 테이블 구조는 존재한다고 가정)




첫 번째 WHEN 절이 TRUE로 평가되면 ORACLE 서버가 해당 INTO절을 실행합니다.

후속 WHEN 절에서는 위의 행을 건너뛰고 실행합니다.




예제3. 아래와 같은 테이블이 있다고 가정하자


[고객_나이]


주소

UNDER_30 

 UNDER_40

OTHER

 서울

 30000

 

 

 서울

 10000

 

 

 파주

 25000

 


 제주

 

 1000

 

 null

 

 

 15000

(Create 시 sql keyword 주의하기: 예, others)



pivoting insert문을 이용하여

나이대에 대한 정보(주소, 총구매액)를 테이블의 data로 만드세요

(고객2 테이블에 INSERT하세요)



무조건 INSERT ALL문으로 PIVOTING 작업을 하였습니다.

PIVOTING INSERT 문은 컬럼이 데이터가 되어 INSERT가 되는 구문입니다.



[결과]


 주소

 나이

 총구매액

 서울

 UNDER_30 

 30000 

 서울 

 UNDER_30  

 100000

 파주

 UNDER_30 

 25000

 제주

 UNDER_30

 (NULL)

 (NULL)

 UNDER_30

 (NULL)

 서울

 UNDER_40

 (NULL)

 서울

 UNDER_40

 (NULL)

 파주

 UNDER_40

 (NULL)

 제주

 UNDER_40

 1000

 (NULL)

 UNDER_40 (NULL)

 ...

 OTHER

 (NULL)



PIVOT를 모르면 여기에서


추가) PIVOTING은 데이터 분석을 위해 수집된 데이터가 엑셀형태일 경우

DB 에 저장해서 분석하고자 할 때 유용하게 사용할 수 있습니다





오늘은 여기까지!


내일 또 돌아올겠습니다. 


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

반응형
반응형



안녕하세요~


오늘은 두 집합을 연결하는 또 다른 연산자 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으로 돌아올겠습니다!



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



반응형
반응형

출처: https://www.gettyimages.com



그룹함수란 무엇일까요?



그룹함수는 여러 개의 행 데이터를 집합 연산을 수행하여


하나의 결과로 출력하는 함수입니다!





 1. MAX: 최대값을 출력하는 함수


 2. MIN: 최소값을 출력하는 함수


 3. SUM: 총합을 구하는 함수


 4. AGE: 평균값을 구하는 함수


 5. COUNT: 테이블의 행의 수를 세는 함수


 이외에 STDDEV, VARIANCE 함수도 포함합니다.



위의 함수는 모두 복수행 함수(그룹함수)입니다.


복수행 함수의 특징을 2가지를 살펴보겠습니다.



우선, 설명을 원활히 하기 위해 아래와 같이 EMP 테이블이 있다고 가정하겠습니다.


사원명

나이

직업

연봉 

보너스

 A

 35

  NULL

 NULL

 

 B

 34

  SALESMAN

 1600

 300

 C

 38

  PRESIDENT

 5000

 

 D

 36

  SALESMAN

 1400

 0

 E

 39

  ANALYST

 3000

 

 F

 32

  SALESMAN

 1350

 500

 G

 37

  MANAGER

 2850

 

 H

 35

  ANALYST

 3000

 

 I

 36

  SALESMAN

 1700

 1400




첫번째 특징, NULL 값을 무시합니다.



문제1. 전체 직업의 평균 연봉을 알고싶다.


 SELECT avg( 연봉 )

FROM emp;


결과a. 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 8


결과b. 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 9




그렇다면 결과 b처럼 연봉컬럼에서 null값을 가진 A도 포함하여 계산하고 싶다면 어떻게 해야할까요?



바로 이때 사용할 수 있는 함수는


 NVL, NVL2, COALESCE, CASE, DECODE 함수 사용할 수 있습니다.


저는 NVL함수를 이용하여


결과b처럼 전체 사원 수로 출력되도록 SQL문을 작성해보겠습니다.



  SELECT avg( nvl ( 연봉, 0 ) )

FROM emp;



nvl 함수를 이용하면 null 값을 0 대신하여 출력할 수 있습니다.


따라서 결과는 0 + 1600 + 5000 + 1400 + 3000 + 1350 + 2850 + 3000 + 1700 / 9 로 출력됩니다.




문제2. 아래의 두 SQL의 결과는 같을까? 다를까?


SQL1> SELECT sum( 보너스 ) from emp;


SQL2> ELECT sum( nvl( 보너스, 0) ) from emp;





하지만 현재 emp 테이블에서


null 값이 많이 들어있는 보너스와 같은 컬럼의 경우 


두번째 SQL 문과 같이 null 값을 0 으로 바꾸어 계산한다면


속도면에서 성능이 떨어지게 되겠죠?



결국 SQL의 성능을 생각한다면


첫 번째 SQL과 같이 SQL을 작성해야합니다!




두번째 특징, 각각은 GROUP BY절과 함께 사용할 수 있습니다.



문제1. 직업이 SALESMAN인 사원들 중에서 최대 월급을 알고싶습니다.




WHERE 절은 데이터 검색 조건을 기술하는 절입니다.


따라서 위의 경우 직업이 SALESMAN 인 사원들을 의미합니다.



결론적으로 위의 SQL을 해석하면


① 직업이 SALESMAN인 사원들을 검색 조건으로,

즉 직업이 SALESMAN인 사원만을 선택하여


② 최대값을 구하는 함수를 사용하여 최대 월급을 구하는 것입니다.




문제2. 직업과 직업별 최대 연봉을 알고 싶습니다.




GROUP BY절의 역할은 직업 data를 그룹핑하는 것입니다.


따라서 직업별로 어떠한 값을 구하고자 할 때는 GROUP BY 함수를 이용하여 구할 수 있습니다.



여기서 잠깐!


GROUP BY절에서 조건을 기술할 수 있는 절은 무엇일까요?


 a. WHERE절


 b. HAVING절





그 이유는 실행 순서와 관련이 있습니다.



이해를 위한 추가문제! 아래의 SQL의 실행순서는 어떻게 될까요?


 

 ⓐ SELECT절


 ⓑ FROM절


 ⓒ WHERE절


 ⓓ GROUP BY절


 ⓔ HAVING절


 ⓕ ORDER BY절

 


참고) 위의 순서는 코드순서입니다.

 




추가문제를 통해 알 수 있듯


GROUP BY절은 WHERE절 이후에 실행됩니다.


즉, WHERE절에서 실행되는 순간에는  GROUP BY를 통한 데이터 그룹핑은 일어나지 않습니다.



따라서 GROUP BY를 통한 결과값을 갖는 그룹함수는 HAVING절로 검색조건을 줄 수 있습니다.



오늘은 여기까지!


주말엔 쉽니다~ 월요일에 다시 만나요 우리~




반응형

+ Recent posts