Pivot 와 Unpivot

Pivot 와 Unpivot
간단 한 SQL 을 사용 하여 스프 레 드 시트 형식의 교차 표 보고 서 를 사용 하여 모든 관계 표 의 정 보 를 표시 하고 교차 표 의 모든 데 이 터 를 관계 표 에 저장 합 니 다.
Pivot
알다 시 피 관계 표 는 표 화 된 것 입 니 다.즉,열-값 이 맞 는 형식 으로 나타 납 니 다.시계 이름 이 CUSTOMERS 라 고 가정 해 봐.
SQL> desc customers


Name Null? Type


----------------------------------------- -------- ---------------------------


CUST_ID NUMBER(10)


CUST_NAME VARCHAR2(20)


STATE_CODE VARCHAR2(2)


TIMES_PURCHASED NUMBER(3)

이 테이블 선택:
select cust_id, state_code, times_purchased


from customers


order by cust_id;

출력 결 과 는 다음 과 같 습 니 다.
CUST_ID STATE_CODE TIMES_PURCHASED


------- ---------- ---------------


1 CT 1


2 NY 10


3 NJ 2


4 NY 4


...and so on

...

데이터 가 어떻게 줄 값 으로 표시 되 는 지 주의 하 십시오.모든 고객 에 게 이 기록 은 고객 이 있 는 주 와 이 고객 이 상점 에서 쇼핑 하 는 횟수 를 보 여 줍 니 다.이 고객 이 상점 에서 더 많은 아 이 템 을 구 매 할 때,열 timesbuddy 에서 업 데 이 트 를 진행 합 니 다.
현재,만약 에 귀하 가 하나의 보고 서 를 통계 하여 각 주의 구 매 빈 도 를 파악 하고 싶다 고 가정 하 십시오.즉,각 주 에 몇 명의 고객 이 한 번,두 번,세 번 만 구 매 하 는 지 등 입 니 다.일반적인 SQL 을 사용 하면 다음 문 구 를 실행 할 수 있 습 니 다.
select state_code, times_purchased, count(1) cnt


from customers


group by state_code, times_purchased;

출력 은 다음 과 같 습 니 다:
ST TIMES_PURCHASED        CNT


-- --------------- ----------


CT 0 90


CT 1 165


CT 2 179


CT 3 173


CT 4 173


CT 5 152


...and so on

...

이것 이 바로 당신 이 원 하 는 정보 입 니 다.그러나 보기에 그다지 불편 합 니 다.교차 표 보고 서 를 사용 하면 이 데 이 터 를 더 잘 표시 할 수 있 습 니 다.그러면 데 이 터 를 수직 으로 배열 하고 각 주 를 수평 으로 배열 할 수 있 습 니 다.마치 스프 레 드 시트 와 같 습 니 다.
Times_purchased


CT NY NJ ...and so on

...





1 0 1 0 ...


2 23 119 37 ...


3 17 45 1 ...


...and so on

...

Oracle 데이터베이스 11g 이 출시 되 기 전에 모든 값 에 대해 decode 함 수 를 통 해 이상 의 작업 을 하고 서로 다른 값 을 하나의 열 로 작성 해 야 합 니 다.그러나 이 방법 은 조금도 직관 적 이지 않다.
다행히도,당신 은 현재 매우 좋 은 새로운 기능 을 사용 할 수 있 습 니 다.PIVOT 는 새로운 조작 자 를 통 해 교차 표 형식 으로 모든 조 회 를 표시 할 수 있 습 니 다.이 조작 자 는 상응 하 게 pivot 라 고 부 릅 니 다.다음은 검색 의 작성 방식 입 니 다:
select * from (


select times_purchased, state_code


from customers t


)


pivot


(


count(state_code)


for state_code in ('NY','CT','NJ','FL','MO')


)


order by times_purchased


/

출력 은 다음 과 같 습 니 다:
. TIMES_PURCHASED       'NY'       'CT'       'NJ'       'FL'       'MO'


--------------- ---------- ---------- ---------- ---------- ----------


0 16601 90 0 0 0


1 33048 165 0 0 0


2 33151 179 0 0 0


3 32978 173 0 0 0


4 33109 173 0 1 0


... and so on ...

이것 은 pivot 조작 부호 의 위력 을 나타 낸다.state_codes 는 열 이 아 닌 제목 줄 로 표 시 됩 니 다.다음은 전통 적 인 표 화 된 형식의 그림 입 니 다.
그림 1 전통 적 인 표 화 디 스 플레이
교차 표 보고서 에서 Times Purchased 열 위 치 를 제목 줄 로 바 꾸 고 싶 습 니 다.그림 2 참조.이 열 은 시계 반대 방향 으로 90 도 회전 하여 제목 줄 로 변 하 는 것 처럼 줄 로 변 한다.이 상징적 인 회전 은 지점(pivot point)이 필요 합 니 다.이 예 에서 이 지점 은 count(statecode)표현 식.
그림 2 에서 Pivot 작업 의 디 스 플레이 를 실 행 했 습 니 다.
이 표현 식 은 다음 과 같은 검색 문법 을 사용 해 야 합 니 다.
...


pivot


(


count(state_code)


for state_code in ('NY','CT','NJ','FL','MO')


)


...

두 번 째 줄"for statecode..."검색 대상 이 이 값 만 제한 합 니 다.이 줄 은 필요 하기 때문에 불행 하 게 도 가능 한 값 을 미리 알 아야 합 니 다.이 제한 은 XML 형식 으로 조 회 될 것 이 며,본문 뒷부분 에서 말 한 바 와 같이 완 화 될 것 이다.
출력 제목 줄 주의:
. TIMES_PURCHASED       'NY'       'CT'       'NJ'       'FL'       'MO'


--------------- ---------- ---------- ---------- ---------- ----------

열 제목 은 표 자체 의 데이터:주 코드 입 니 다.줄 임 말 은 더 이상 설명 할 필요 가 없 을 수도 있 지만 줄 임 말 대신 주 이름 을 표시 하고 싶다 면 어떻게 해 야 합 니까?만약 그렇다면,다음 과 같이 조 회 된 FOR 자구 에서 조정 을 해 야 합 니 다.
select * from (


select times_purchased as "Puchase Frequency", state_code


from customers t


)


pivot


(


count(state_code)


for state_code in ('NY' as "New York",'CT' "Connecticut",'NJ' "New Jersey",'FL' "Florida",'MO' as "Missouri")


)


order by 1


/





Puchase Frequency New York Connecticut New Jersey Florida Missouri


----------------- ---------- ----------- ---------- ---------- ----------


0 16601 90 0 0 0


1 33048 165 0 0 0


2 33151 179 0 0 0


3 32978 173 0 0 0


4 33109 173 0 1 0


...and so on

...

FOR 자 구 는 그 값(이 값 들 은 열 제목 이 될 것 입 니 다)의 별명 을 제공 할 수 있 습 니 다.
Unpivot
물질 이 있 으 면 반 물질 이 있 는 것 처럼 pivot 가 있 으 면'unpivot'가 있어 야 합 니 다.그 렇 죠?
자,농담 은 아니 지만 pivot 의 역방향 조작 이 필요 합 니 다.교차 표 보고 서 를 표시 하 는 스프 레 드 시트 가 있다 고 가정 하면 다음 과 같 습 니 다.
 
Purchase Frequency
New York
Connecticut
New Jersey
Florida
Missouri
0
12
11
1
0
0
1
900
14
22
98
78
2
866
78
13
3
9
...
.
 
 
 
 
현재 이 데 이 터 를 CUSTOMERS 라 는 관계 표 에 불 러 오 기 를 원 합 니 다.
SQL> desc customers


Name Null? Type


----------------------------------------- -------- ---------------------------


CUST_ID NUMBER(10)


CUST_NAME VARCHAR2(20)


STATE_CODE VARCHAR2(2)


TIMES_PURCHASED NUMBER(3)

스프 레 드 시트 데 이 터 를 관계 형식 으로 규범화 한 다음 에 저장 해 야 한다.물론,DECODE 를 사용 하여 복잡 한 SQL*:Loader 또는 SQL 스 크 립 트 를 작성 하여 데 이 터 를 CUSTOMERS 표 에 불 러 올 수 있 습 니 다.또는,pivot 의 역방향 조작 UNPIVOT 를 사용 하여 열 을 줄 로 바 꿀 수 있 습 니 다.이것 은 Oracle 데이터베이스 11g 에서 이 루어 집 니 다.
예 시 를 통 해 이 를 보 여 주 는 것 이 더 간단 할 것 이다.우선 pivot 작업 을 사용 하여 교차 표를 만 듭 니 다:
1  create table






cust_matrix


2 as


3 select * from (


4 select times_purchased as "Puchase Frequency", state_code


5 from customers t


6 )


7 pivot


8 (


9 count(state_code)


10 for state_code in ('NY' as "New York",'CT' "Conn",'NJ' "New Jersey",'FL' "Florida",


'MO' as "Missouri")


11 )


12* order by 1

표 에 저 장 된 데 이 터 를 볼 수 있 습 니 다:
SQL> select * from cust_matrix


2 /





Puchase Frequency New York Conn New Jersey Florida Missouri


----------------- ---------- ---------- ---------- ---------- ----------


1 33048 165 0 0 0


2 33151 179 0 0 0


3 32978 173 0 0 0


4 33109 173 0 1 0


... and so on ...

이것 은 데이터 가 스프 레 드 시트 에 저장 되 는 방식 이다.각 주 는 표 의 한 열("New York","Conn"등)이다.
SQL> desc cust_matrix


Name Null? Type


----------------------------------------- -------- ---------------------------


Puchase Frequency NUMBER(3)


New York NUMBER


Conn NUMBER


New Jersey NUMBER


Florida NUMBER


Missouri NUMBER

주 코드 와 주 쇼핑 인원 만 표시 할 수 있 도록 시 계 를 흐 트 러 뜨 려 야 합 니 다.unpivot 작업 을 통 해 이 목적 을 달성 할 수 있 습 니 다.다음 과 같 습 니 다.
select *


from cust_matrix


unpivot


(


state_counts


for state_code in ("New York","Conn","New Jersey","Florida","Missouri")


)


order by "Puchase Frequency", state_code


/

출력 은 다음 과 같 습 니 다:
Puchase Frequency STATE_CODE STATE_COUNTS


----------------- ---------- ------------


1 Conn 165


1 Florida 0


1 Missouri 0


1 New Jersey 0


1 New York 33048


2 Conn 179


2 Florida 0


2 Missouri 0


...and so on

...

각 열 이름 이 어떻게 STATE 로 변 하 는 지 주의 하 세 요.CODE 열 에 있 는 값 입 니 다.Oracle 은 state 를 어떻게 압 니까?code 는 열 이름 입 니까?이것 은 조회 중의 자 구 를 통 해 알 수 있 습 니 다.다음 과 같 습 니 다.
for state_code in ("New York","Conn","New Jersey","Florida","Missouri")

"New York","Conn"등 값 을 지정 하면 unpivot 작업 을 수행 할 state 입 니 다.code 새 열의 값 입 니 다.일부 원시 데 이 터 를 살 펴 보 자.
Puchase Frequency   New York       Conn New Jersey    Florida   Missouri


----------------- ---------- ---------- ---------- ---------- ----------


1 33048 165 0 0 0

'뉴욕'이 갑자기 한 줄 의 값 으로 바 뀌 었 을 때,당신 은 어떻게 값 33048 을 표시 합 니까?이 값 은 어느 열 아래 에 표시 해 야 합 니까?상기 조회 에서 unpivot 연산 자 에 있 는 for 자구 위의 자구 에 대해 해답 을 하 였 다.state 를 지정 하 셨 습 니 다counts,이것 은 생 성 된 출력 에서 만 든 새 열의 이름 입 니 다.
Unpivot 는 pivot 의 역방향 조작 일 수 있 지만 전자 가 후자 가 하 는 모든 조작 에 대해 역방향 조작 을 할 수 있다 고 생각 하지 마 세 요.예 를 들 어 상기 예제 에서 CUSTOMERS 표 에 pivot 작업 을 사용 하여 새 표 CUST 를 만 들 었 습 니 다.MATRIX。그리고 당신 은 CUSTMATRIX 시 계 는 unpivot 를 사 용 했 지만 원본 시계 인 CUSTOMERS 의 상세 한 정 보 를 되 찾 지 못 했다.반면,교차 표 보고 서 는 관계 표 에 데 이 터 를 불 러 오 는 다른 방식 으로 표시 할 수 있 습 니 다.따라서 unpivot 는 pivot 를 취소 하기 위 한 작업 이 아 닙 니 다.pivot 를 사용 하여 시 계 를 만 들 고 원본 시 계 를 삭제 하기 전에 신중하게 고려 해 야 합 니 다.
unpivot 의 일부 재 미 있 는 용법 은 일반적인 강력 한 데이터 조작 기능 범 위 를 초과 했다(예 를 들 어 위의 예제).Amis Technologies 의 Oracle ACE 총괄 인 Lucas Jellema 는 테스트 에 사용 할 몇 줄 의 특정 데 이 터 를 만 드 는 방법 을 소개 했다.영어 알파벳 의 모음 을 표시 하기 위해 서 나 는 그의 원본 코드 를 약간 수정 할 것 이다.
select value


from


(


(


select


'a' v1,


'e' v2,


'i' v3,


'o' v4,


'u' v5


from dual


)


unpivot


(


value


for value_type in


(v1,v2,v3,v4,v5)


)


)


/

출력 은 다음 과 같 습 니 다:
V


-


a


e


i


o


u

이 모델 은 모든 종류의 줄 생 성기 로 확장 할 수 있 습 니 다.루 카 스 가 우리 에 게 이 교묘 한 수법 을 제공 해 준 것 에 감사 드 립 니 다.
XML 형식
상기 예시 에서 유효한 state 를 지정 하 는 것 을 주의 하 십시오codes 방식:
for state_code in ('NY','CT','NJ','FL','MO')

state 를 안다 고 가정 해 야 합 니 다.코드 열 에 표 시 된 값 입 니 다.어떤 값 이 있 는 지 모 르 시 면 조 회 를 어떻게 구축 하 시 겠 습 니까?
pivot 작업 의 다른 키 문장 XML 은 이 문 제 를 해결 하 는 데 사용 할 수 있 습 니 다.이 절 은 pivot 작업 을 수행 하 는 출력 을 XML 형식 으로 만 들 수 있 습 니 다.이 출력 에서 텍스트 값 이 아 닌 특수 한 절 ANY 를 지정 할 수 있 습 니 다.예 는 다음 과 같다.
select * from (


select times_purchased as "Purchase Frequency", state_code


from customers t


)pivot xml

(


count(state_code)for state_code in (any)

)


order by 1


/

출력 을 CLOB 로 복원 하여 LONGSIZE 가 검색 이 실행 되 기 전에 큰 값 으로 설정 하도록 합 니 다.
SQL> set long 99999

원본 pivot 작업 에 비해 이 조 회 는 두 가지 가 뚜렷하게 다르다(굵 은 몸 으로 표시).우선,pivot 가 아 닌 키 문장 pivot xml 을 지정 하 였 습 니 다.이 절 은 XML 형식의 출력 을 생 성 합 니 다.다음,for 자구 표시 for statecode in(any)긴 목록 이 아 닌 state코드 값.이 XML 표현법 은 ANY 키 워드 를 사용 할 수 있 습 니 다.state 를 입력 할 필요 가 없습니다.코드 값.출력 은 다음 과 같 습 니 다:
Purchase Frequency STATE_CODE_XML


------------------ --------------------------------------------------


1 CT

lumn>165

n>
NY

umn>33048

mn>






2 CT

lumn>179

n>
NY

umn>33151

mn>






... and so on ...

보시 다시 피,열 STATECODE_XML 은 XML TYPE 이 며,그 중 뿌리 원 소 는.각 값 은 이름-값 요소 가 맞 는 형식 으로 표 시 됩 니 다.XML 분석 기의 출력 을 사용 하여 더 유용 한 출력 을 만 들 수 있 습 니 다.
ANY 자구 외 에 도 하위 조 회 를 작성 할 수 있 습 니 다.우선 주 목록 이 있다 고 가정 하고 이 주 들 의 줄 만 선택 하 기 를 원 합 니 다.우선 주 를 preferred 라 는 이름 으로 두 십시오.states 의 새 표 중:
SQL> create table preferred_states


2 (


3 state_code varchar2(2)


4 )


5 /





Table created.





SQL> insert into preferred_states values ('FL')


2> /





1 row created.





SQL> commit;





Commit complete.

현재 pivot 작업 은 다음 과 같 습 니 다:
select * from (


select times_purchased as "Puchase Frequency", state_code


from customers t


)


pivot xml


(


count(state_code)


for state_code in (select state_code from preferred_states)


)


order by 1


/

for 자구 의 하위 조 회 는 당신 이 필요 로 하 는 모든 내용 일 수 있 습 니 다.예 를 들 어 모든 기록 을 선택 하고 그 어떠한 우선 주 에 국한 되 지 않 으 려 면 다음 과 같은 내용 을 for 자구 로 사용 할 수 있 습 니 다.
for state_code in (select distinct state_code from customers)

하위 조 회 는 다른 값 을 되 돌려 야 합 니 다.그렇지 않 으 면 조회 가 실 패 됩 니 다.이것 이 바로 우리 가 상술 한 DISTINCT 자 구 를 지정 한 이유 이다.
결론.
Pivot 는 SQL 언어 에 매우 중요 하고 실 용적 인 기능 을 추가 했다.pivot 함 수 를 사용 하여 모든 관계 표 에 대해 교차 표 보고 서 를 만 들 수 있 습 니 다.decode 함 수 를 많이 포함 하 는 이해 하기 어렵 고 직관 적 이지 않 은 코드 를 만 들 필요 가 없습니다.마찬가지 로 unpivot 작업 을 통 해 모든 교차 표 보고 서 를 변환 하고 일반적인 관계 표 형식 으로 저장 할 수 있 습 니 다.Pivot 는 일반적인 텍스트 나 XML 형식의 출력 을 생 성 할 수 있 습 니 다.XML 형식의 출력 이 라면 검색 할 값 영역 을 지정 할 필요 가 없습니다.
pivot 와 unpivot 작업 에 대한 상세 한 정 보 는 Oracle 데이터베이스 11g SQL 언어 참고
 
 
전환 하 다http://space.itpub.net/1384/viewspace-217977

좋은 웹페이지 즐겨찾기