2011-10-11 4 views
22

オラクルに動的に列に行をピボット:私は、次のOracle 10gのテーブルが_kvと呼ばれている

select * from _kv 

ID  K  V 
----  ----- ----- 
    1  name Bob 
    1  age  30 
    1  gender male 
    2  name Susan 
    2  status married 

たように、私はプレーンなSQL(ないPL/SQL)を使用して列に私のキーを有効にしたいですテーブルには、次のようになります。

ID  NAME AGE GENDER STATUS 
----  ----- ----- ------ -------- 
    1  Bob  30  male 
    2  Susan     married 
  • ユニークK sが(その多くはありません)テーブルに存在してクエリは同じ数の列を持っている必要があり
  • クエリを実行する前に、どの列が存在するかを知る方法がありません。
  • 私はプログラムで最終的なクエリを構築するために、最初のクエリを実行しないようにしようとしています。
  • 空のセルはヌルまたは空の文字列でも構いません。
  • 私はOracle 10gを使用していますが、11gソリューションも問題ありません。

ピボット列が呼び出される可能性がある場合は、多くの例がありますが、Oracle用の一般的なピボット・ソリューションを見つけることはできません。

ありがとうございます!

+5

親愛なる神、...メタDBということです? –

+2

あなたはこれを読むべきです:http://stackoverflow.com/questions/7340422/best-way-to-query-a-data-dictionary-in-sql/7340554#7340554 –

+0

私はいつもこのことを読んでユーモアを見つけました 'エンティティ属性値 'テーブル:http://asktom.oracle.com/pls/apex/f?p=100:11:0:::P11_QUESTION_ID:2314483800346542969 – Harrison

答えて

28

Oracle 11gでは、必要な操作を行うPIVOTオペレーションを提供しています。

Oracle 11gの溶液を

select * from 
(select id, k, v from _kv) 
pivot(max(v) for k in ('name', 'age', 'gender', 'status') 

(注:私はので、私はその機能を確認していないでこれをテストするために11グラムのコピーを持っていない)

私がこのソリューションを取得:http://orafaq.com/wiki/PIVOT

EDIT - ピボットxmlオプション(また、Oracle 11g)
必要な可能性があるすべての列見出しがわからない場合は、明らかにpivot xmlオプションもあります。私はそうでこれをテストするために、11グラムのコピーを持っていない前に、私はその機能を確認していないとして注:(

select * from 
(select id, k, v from _kv) 
pivot xml (max(v) 
for k in (any)) 

http://www.oracle.com/technetwork/articles/sql/11g-pivot-097235.htmlに位置ページの下の方にのXML TYPEセクションを参照してください) )

EDIT2:コメントの一つで述べたように、集約されることになっているのでmax(v)からpivotpivot xmlステートメントでvを変更しました。私はpivotのためのオプションではないin節も追加しました。もちろん、in句の値を指定しなければならないということは、この質問のポスターが望んだように、完全に動的なピボット/クロス集計クエリを持つという目標を打ち破っています。

+0

'pivot(v for k)'部分が11gで動作していない、 'for'が' in'を必要としていて、 'in'節に入れるべきものがわかりません – ojosilva

+1

@dave - PIVOT操作のみ固定列セットで動作します。追加の行が表に追加されるため、問合せで突然列が戻されることはありません。 –

+0

@JustinCave、@ojosilva 'in'節は、列を特定の値に制限したい場合にはオプションであり、すべての値が必要な場合には省略することができると考えました。どうやらこれを扱う 'pivot xml'オプションがあります(更新された答えを見てください)。 – dave

5

ピボットでタスクが発生します。11グラムで今テストし、以下のように私の作品:

select * from 
(
    select ID, COUNTRY_NAME, TOTAL_COUNT from ONE_TABLE 
) 
pivot(
    SUM(TOTAL_COUNT) for COUNTRY_NAME in (
    'Canada', 'USA', 'Mexico' 
) 
); 
6

複数の値(あなたの例ではV)の可能性がある状況に対処するために、私はPIVOTLISTAGGを使用します。

SELECT * FROM 
(
    SELECT id, k, v 
    FROM _kv 
) 
PIVOT 
(
    LISTAGG(v ,',') 
    WITHIN GROUP (ORDER BY k) 
    FOR k IN ('name', 'age','gender','status') 
) 
ORDER BY id; 

動的な値が必要な場合は、動的SQLを使用し、ピボット・ステートメントを呼び出す前にテーブル・データでselectを実行して決定された値を渡します。

0

まず、pivot xmlを使用して動的にピボットを解析する必要があります。変数に列名を格納し、動的SQLに以下のように渡すことで、これを行う別の方法があります。

次のような表があるとします。

enter image description here

私たちが列名として列YRQTYからこれらの列の値に値を表示する必要がある場合は、我々は以下のコードを使用することができます。

declare 
    sqlqry clob; 
    cols clob; 
begin 
    select listagg('''' || YR || ''' as "' || YR || '"', ',') within group (order by YR) 
    into cols 
    from (select distinct YR from EMPLOYEE); 


    sqlqry := 
    '  
    select * from 
    (
     select * 
     from EMPLOYEE 
) 
    pivot 
    (
    MIN(QTY) for YR in (' || cols || ') 
)'; 

    execute immediate sqlqry; 
end; 
/

RESULT

enter image description here

関連する問題