_kvという次のOracle 10gテーブルがあります。
select * from _kv
ID K V
---- ----- -----
1 name Bob
1 age 30
1 gender male
2 name Susan
2 status married
PL/SQLではなくプレーンSQLを使用してキーを列に変換して、結果の表が次のようになるようにします。
ID NAME AGE GENDER STATUS
---- ----- ----- ------ --------
1 Bob 30 male
2 Susan married
K
sと同じ数の列が必要です(それほど多くはありません)ピボット列の名前を知っている場合の例はたくさんありますが、Oracleの一般的なピボットソリューションは見つかりません。
ありがとう!
Oracle 11gは、必要なことを行うPIVOT
操作を提供します。
Oracle 11gソリューション
_select * from
(select id, k, v from _kv)
pivot(max(v) for k in ('name', 'age', 'gender', 'status')
_
(注:これをテストする11gのコピーがないため、機能を確認していません)
私はこのソリューションを以下から入手しました: http://orafaq.com/wiki/PIVOT
EDIT-ピボットxmlオプション(Oracle 11gも)
明らかに、必要な可能性のあるすべての列見出しがわからない場合の_pivot xml
_オプションもあります。 (XML TYPEセクションを参照してください http://www.Oracle.com/technetworkにあるページの下部にあります) /articles/sql/11g-pivot-097235.html )
_select * from
(select id, k, v from _kv)
pivot xml (max(v)
for k in (any) )
_
(注:以前と同様に、これをテストする11gのコピーがないため、機能を確認していません)
Edit2:v
および_pivot xml
_ステートメントのpivot
をmax(v)
に変更コメントの1つで言及されているように集約されることになっています。 in
のオプションではないpivot
句も追加しました。もちろん、in
句で値を指定する必要があるため、この質問のポスターの要望通り、完全に動的なピボット/クロス集計クエリを作成するという目標は無効になります。
複数の値(例ではv)の可能性がある状況に対処するために、PIVOT
とLISTAGG
を使用します。
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を実行することで決定された値を渡します。
ピボットにタスクがあるようになります。以下は、11gで今テストしたとおりに機能します。
select * from
(
select ID, COUNTRY_NAME, TOTAL_COUNT from ONE_TABLE
)
pivot(
SUM(TOTAL_COUNT) for COUNTRY_NAME in (
'Canada', 'USA', 'Mexico'
)
);
まず、pivot xml
を使用した動的なピボットを再度解析する必要があります。これを行う別の方法として、列名を変数に保存し、以下のように動的SQLに渡します。
下のような表があると考えてください。
YR
列の値を列名として表示し、QTY
の列の値を表示する必要がある場合、以下のコードを使用できます。
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 [〜#〜]