본문 바로가기

오라클 실무..

SQL - 가로로 등록된 데이터를 세로로 펼쳐내기-1

주로 이 쿼리는 세로로 펼쳐야 할 값을 가로로 펼처놓아서,

다시 정규화된 형태인 세로로 펼치고자 하는 경우에 사용됩니다.
또한, 특수한 경우에 값들이 가로의 필드로 나열이 되어 있는 경우에 그 값들을 세로로 보고자 하는

요구가 있는 경우에도 용될 수 있습니다.

이런 형태의 key포인트는 원래 한개인 row가 내가 원하는 만큼의 row로 창출된다는 개념입니다.

이런 형태의 데이터 창출을 위해서는 단지 복제를 하기 위해서 필요한 테이블인 COPY_T의 존재가 필수적입니다.
실제, 이 테이블은 딸랑 한개의 컬럼에 숫자만 들어가 있는 매우 단순한 테이블입니다.
(실제 사례에서는, 데이터타입별로 사용하기 위해서, 같은 값을 가진 문자 컬럼도 함께 표현해 둡니다.) 보통 복제는
20개이상은 하지 않기 때문에 별다른 인덱스조차 만들지 않아도 상관없습니다(한개의 BLOCK안에 모두다 모여있겠죠.)
더구나 10개의 ROW를 넣는데 STORAGE PARAMETER의 INITIAL SPACE를 10M로 잡는다면 어리석은 선택일 것입니다.
각설하고, 실제 COPY_T에는 어떤 데이터들이 들어가 있는지 확인해 봅시다.


이 단순한 테이블이 얼마나 큰 위력을 발휘하는지는 앞으로 많은 부분에서 아시게 될 것입니다.
일단, 우리가 가지고 있는 집합과 만들어내고 싶은 집합을 한번 살펴보기로 합시다.


위의 경우처럼 1월~12월의 판매집계값을 가지고 있는 테이블의 각 월별 값을 세로로 보여주고자 합니다.
물론, 이런 경우에 프로그램에서 일단 데이터를 받은 후에 그 값을 세로로 루프를 돌면서 할 수도 있습니다만,
우리는 그러한 일을 옵티마이저가 알아서 스스로 할 수 있게해주고자 하는 것이 목적이고,
대량의 데이터 마이그레이션의 경우 별도의 UI없이 쿼리에서만 수행하는 것이 대부분이므로 쿼리로 해결을 하겠습니다.

먼저, 위의 행은 모든 데이터가 가로로 12개씩 펼쳐져 있다는 것에 주목할 필요가 있습니다.
그렇다면, 1개의 ROW를 12개의 ROW로 나누어내는 것이 가장 선행되어야 할 것입니다.
또한, 펼쳐진 월이 1~12까지의 월(즉, 1~12까지의 숫자로 구성되었다)는 점에 주목할 필요가 있습니다.
일반적으로 두개의 테이블을 아무런 조건없이 조인하면 양집합간의 곱
(A테이블이 100개,B테이블이 10개의 ROW를 가진 집합이었다고 가정하면 1000개의 ROW를 가진 집합)
이 만들어 진다는 것은 누구나 아는 사실일 것입니다.

따라서, 우리는 COPY_T의 ROW가 20개라 하더라도12개의 ROW만가진 집합으로 만들어서 조건없이 조인을 한다면,
판매집계테이블이 가진 모든 행이 12개씩의 복제된 결과집합으로 만들어지게 된다는 것을 아시겠지요.
이 말을 풀어서 쿼리로 작성한 것이 아래의 예입니다.


이 쿼리를 보시면, 판매집계테이블과 copy_t테이블의 연관관계에 대한 정의는 하나도 없습니다.
단지 b테이블이 가진 많은 row중에서 sn_n이 13보다 작은 즉, 12개의 row만을 가지고 cartesian product를 만들라는 것입니다.
그렇다면 아래와 같이 복제가 되어 있겠네요.


이제 이 데이터를 보면 감이 좀 오나요. 1월은 COPY_T에 의해서 첫번째로 복제된 ROW의 숫자와 그 월의 숫자가 일치합니다.
2월은 COPY_T의 두번째 숫자인 2와 동일하죠. 그래서 ... 하다보면 12월까지 모두 채워지게 되었습니다.
위의 그림집합에서 우리가 뽑아내야할 데이터는 아래와 같습니다.


그것도 그냥 뽑아내는 것이 아니라 하나의 컬럼으로 몰아서 가져와야 하죠.
머 그러나 별로 어려운 일은 아닙니다. 아래의 쿼리를 통해서 하나로 모으는것은 아주 쉬워지죠.


만약 위의 값을 가지고 분기별 합계나, 부서별 합계 등을 뽑는다면 SN_N이 유용하게 사용될 수 있으므로
또한 어느월에 판매된 금액인지 구분을 위해서 SN_N을 삽입하였습니다. 이제 응용은 얼마든지 가능하겠죠? ^^~