列tname, ttype
の値のペアの定義された数の場合 以下のクエリを使用できます(ここでOracleキーワードを使用したため、例から列名を変更したことに注意してください。また、テーブルにtasks
という名前を付けました。 、したがって、このデータをコード内のすべての場所で実際の列名とテーブル名に変更する必要があります):
select * from tasks
pivot (max(tdate) for (tname, ttype) in
(('DG1','CF') DG1_CF, ('M0','A') M0_A, ('M0','POR') M0_POR,
('M1','A' ) M1_A, ('M1','CF') M1_CF, ('M2','A') M2_A)));
動的な数の可能性については、このクエリを「作成」する手順が必要になります。ここではview
を使用しました このために、プロシージャコードをコピーしてコンパイルします。テーブル内のデータが変更された場合は、最初にプロシージャを実行してから、プロシージャによって作成されたビューから選択する必要があります。スキーマを正しく実行するには、付与されたビューを作成するための特権が必要です。
execute create_tasks_view;
select * from v_tasks;
anonymous block completed
ID DG1_CF M0_A M0_POR M1_A M1_CF M2_A
----- ---------- ---------- ---------- ---------- ---------- ----------
45000 2015-03-02 2015-02-01 2015-03-11 2015-02-03 2015-03-01 2015-02-04
44400 2015-02-02 2015-01-01 2015-02-11 2015-01-03 2015-02-01 2015-01-04
もちろん、order by
を追加または変更することで、行と列の順序を自由に変更できます。 プロシージャコードのパーツ:
create or replace procedure create_tasks_view as
v_sql varchar2(32767) := '';
begin
for v in (select distinct tname, ttype from tasks order by tname, ttype)
loop
v_sql := v_sql || '(''' || v.tname || ''',''' || v.ttype || ''') '
||v.tname||'_'||v.ttype||',';
end loop;
v_sql := 'create or replace view v_tasks as '
||'select * from tasks pivot (max(tdate) for (tname, ttype) in ('
||rtrim(v_sql, ', ')||'))';
execute immediate v_sql;
end create_tasks_view;
コメントであなたに与えたリンクであなたの質問に対するより普遍的な解決策もあると思います:動的SQLピボット... 。非常に有望に見えます。リソースのセクションをよく読んでください。 下部にあり、指示の手順に従います。私はこの方法を個人的にチェックしませんでしたが、おそらくこれは私の「プロシージャビュー」ソリューションよりも適しているでしょう。