2016-08-01 3 views
2

다양한 열의 항목이 열 머리글에 피벗 된 테이블을 만들고 싶습니다. 이 표는보고 용입니다. Microsoft Query를 사용하여 Excel을 통해 데이터를 쿼리하려는 경우 Excel에서 피벗을 수행하면 보통 크기의 데이터 세트 (~ 100k 데이터 포인트)의 경우에도 파일이 실제로 크기가 커지고 느려집니다.).Oracle SQL : 여러 열/피벗의 피벗

CREATE TABLE tt 
( 
    "COMMODITY" VARCHAR2(4000 BYTE), 
    "MARKET" VARCHAR2(4000 BYTE), 
    "BID_ASK" VARCHAR2(4000 BYTE), 
    "PRICE"  NUMBER 
); 

INSERT INTO tt VALUES ('Gold','US','Ask',1.1); 
INSERT INTO tt VALUES ('Gold','US','Bid',1); 
INSERT INTO tt VALUES ('Gold','EU','Ask',1.2); 
INSERT INTO tt VALUES ('Gold','EU','Bid',1.1); 
INSERT INTO tt VALUES ('Oil','US','Ask',11); 
INSERT INTO tt VALUES ('Oil','US','Bid',10); 
INSERT INTO tt VALUES ('Oil','EU','Ask',12); 
INSERT INTO tt VALUES ('Oil','EU','Bid',11); 

내가 같은 것이다 달성하려는 출력 (정확한 열 머리글은별로 중요하지 않음) :

COMMODITY 'US_Bid' 'US_Ask' 'EU_Bid' 'EU_Ask' 
Gold   1   1.1   1.1  1.2 
Oil   10   11   11   12 

지금은 간단합니다

는 다음과 같은 예를 생각해 단일 열을 피봇 팅합니다.

SELECT * FROM 
(
    SELECT * FROM tt 
) 
PIVOT 
(
    SUM(PRICE) 
    FOR MARKET IN ('US','EU') 
) 

다음은 다음을 제공합니다.

COMMODITY BID_ASK 'US' 'EU' 
Gold  Bid  1  1.1 
Oil   Bid  10  11 
Oil   Ask  11  12 
Gold  Ask  1.1 1.2 

제 연구에 따르면 여러 열을 직접 피벗하는 구문은 없습니다. 관련 질문 (here, here 또는 here)이 있지만 내 문제에 대한 직접적인 대답을 찾을 수 없습니다. 그래서 다음 해결책을 생각해 냈습니다.

SELECT * FROM 
(
    SELECT COMMODITY, CONCAT(CONCAT(MARKET,'_'),BID_ASK) AS MARKET_BID_ASK, PRICE FROM tt 
) 
PIVOT 
(
    SUM(PRICE) 
    FOR MARKET_BID_ASK IN ('US_Bid','US_Ask','EU_Bid','EU_Ask') 
) 

이렇게하면 원하는 출력이 정확하게 생성됩니다. 그러나 입력해야하는 변수의 수가 너무 빠름에 따라 실용적인 솔루션으로 생각하지 않습니다. (실제 데이터 세트에서 한 번에 더 많은 필드를 피벗하고 싶습니다. 모든 필드에는 많은 값이 있습니다.) 나는 dynamic pivots이 존재한다는 것을 알고 있지만 Excel에서 작동하는지 확신 할 수 없으며 사용자가 직접 쿼리를 정의하기 때문에 구문을 가능한 한 간단하게 유지하려고합니다 (템플릿을 제공하려고합니다.) 그들이 적응할 수있는 쿼리).

SELECT * FROM 
(
    SELECT COMMODITY, CONCAT(CONCAT(MARKET,'_'),BID_ASK) AS MARKET_BID_ASK, PRICE FROM tt 
) 
PIVOT 
(
    SUM(PRICE) 
    FOR MARKET_BID_ASK IN 
    (
    SELECT DISTINCT CONCAT(CONCAT(MARKET,'_'),BID_ASK) AS MARKET_BID_ASK FROM tt 
) 
) 

내가 하나 여전히 같은 -를 사용하여 모든 연결된 옵션을 나열하지 않고도 쿼리 변수를 제한 할 수 있기 때문에 이러한 솔루션이 실제가 될 수 있다고 생각 : 그래서 IN-절에서 필드 이름을 조회하려고 하위 쿼리의 조건 그러나 하위 쿼리는 여기에서 발견 된 documentation에 따라 여기에 합법적이어야하지만이 쿼리에서는 "ORA-00936 - 누락 된 표현식"오류가 발생합니다.

+0

이 링크 http://stackoverflow.com/questions/38651147/how-to-transpose-column-into-row-in-oracle-sql-11g/38653133#38653133을 참조하고 ** select *에서 시도하십시오. 테이블에서 (피벗 (Q '$ 선택 상품, CONCAT (시장,'_ '), BID_ASK AS MARKET_BID_ASK, 가격 $ tt')) ** –

+0

다이내믹 SQL은 정확하게 피벗 필드를해야 할 때 갈 방법입니다 런타임시 사용자가 정의합니다.사용자 선택에 따라 SQL 명령 텍스트를 작성할 VBA 함수를 만듭니다. – Serg

+2

"문서"가 잘못 나온 것 같습니다. [공식 문서] (https://docs.oracle.com/database/121/SQLRF/statements_10002.htm#CHDFAFIE)를 참조하면 하위 쿼리 옵션이 XML 키워드와 함께 허용된다는 것을 알 수 있습니다. – jpw

답변

4

당신은 열을 둘러싸고 여러 열을 돌리고 있습니다 괄호 안의 값의 세트 :

SELECT * FROM 
(
    SELECT * FROM tt 
) 
PIVOT 
(
    SUM(PRICE) 
    FOR (MARKET, BID_ASK) 
    IN (('US', 'Bid') us_bid, ('US', 'Ask') us_ask, ('EU', 'Bid') eu_bid, ('EU', 'Ask') eu_ask) 
); 

COMMODITY  US_BID  US_ASK  EU_BID  EU_ASK 
---------- ---------- ---------- ---------- ---------- 
Gold    1  1.1  1.1  1.2 
Oil    10   11   11   12 

하지만 값 쌍은 여전히 ​​쿼리 구문 분석 할 때 알려진, 이것은 '아무튼되어야한다 값의 조합이 많은 경우에는 규모를 잘 조정하십시오.

Excel에서 XML 피벗 결과를 처리 할 수 ​​없다면 의심되는 것처럼 유일한 대안은 동적 SQL입니다. 이는 가능하지 않다고 생각합니다. 동적 SQL을 사용하면 쿼리 및 피벗을 수행하고 참조 커서를 반환하는 함수가있을 수 있습니다 (Excel에서 피벗 쿼리보다 처리하기가 쉬운 경우).