2017-03-10 7 views
-1

key1を識別カラムとして保持することによって、以下の変換を適用する必要があります。同じキーを持つ列の行の値をコピーする

入力データ

key1 key2 value 
1 val1 x 
1 val2 y 
2 val1 x 
2 val2 z 
3 val2 z 
4 val1 x 
4 val2 y 
4 val2 z 

出力

key1 val1 val2 
1 x  y 
2 x  z 
3 z  z 
4 x  y 
4 x  z 

あなたはself joinを使用するよりも結果を達成するための別の方法を提案することはできますか?

+1

ピボットすることができます(11gから、選択したドキュメントでそのキーワードを検索します)。常に同じ2つのkey2値がありますか?あなたは本当にkey1 = 4の同じkey2の2つの値を持っていますか?キー(または少なくともキーの組み合わせ)は通常ユニークです。 (なぜあなたの行は3のval1をzとして表示しますか?あなたのデータにはありません) –

+0

すべてのキーの値がすべて異なっている可能性があります。私はkey1 = 4に対して同じkey2の2つの値を持っています。 3にはval1をxにすると、xには他のval1は存在しないので、4を表示します。 –

+0

しかし、key2、 'val1'、 'val2'には2つの値しかありませんか?それとも何でもいいの?そして、key1にもval1の値が複数存在することができます。もしそうなら、key1に複数のval1 *と* val2の値があったらどうなるでしょうか? (私はあなたのコメントの2番目の文を理解していない、それはあなたのデータに関連していないようです)。 –

答えて

1

あなたはより多くの仕事、単純なピボットを行う必要が示さてきたように、各key1に対して複数のval2値を持つことができます。キー(またはそれらの組み合わせ)が固有のものではないことを奇妙に思えるし、あなたがkey2値の両方、または単にval2 ...

に複数の値を持つことができる場合、これはあなただけ持つことができると仮定し、完全に明確ではありません

with cte as (
    select key1, key2, value, 
    row_number() over (partition by key1, key2 order by key2) as key2_rn 
    from mytable 
) 
select distinct key1, 
    max(case when key2 = 'val1' then value end) over (partition by key1) as val1, 
    max(case when key2 = 'val2' then value end) over (partition by key1, key2_rn) as val2 
from cte; 

別のCTEにあなたのサンプルデータを模倣::

with mytable (key1, key2, value) as (
    select 1, 'val1', 'x' from dual 
    union all select 1, 'val2', 'y' from dual 
    union all select 2, 'val1', 'x' from dual 
    union all select 2, 'val2', 'z' from dual 
    union all select 3, 'val2', 'z' from dual 
    union all select 4, 'val1', 'x' from dual 
    union all select 4, 'val2', 'y' from dual 
    union all select 4, 'val2', 'z' from dual 
), 
cte as (
    select key1, key2, value, 
    row_number() over (partition by key1, key2 order by key2) as key2_rn 
    from mytable 
) 
select distinct key1, 
    max(case when key2 = 'val1' then value end) over (partition by key1) as val1, 
    max(case when key2 = 'val2' then value end) over (partition by key1, key2_rn) as val2 
from cte 
order by 1, 2, 3; 
有効な仮定ではないかもしれないが、あなたのサンプルデータがそうでなければ表示されません各 key1のための単一の val1

ができます:

 KEY1 VAL1 VAL2 
---------- ---- ---- 
     1 x y 
     2 x z 
     3  z 
     4 x y 
     4 x z 

問題のサンプル出力が'z'としてval1ためkey1=3列を示しているが、あなたのデータはそれを持っていません。もしそれをval2の値にデフォルト設定しておけば、これも達成可能ですが、それはさらに面倒です。あなたは(11グラムからの)実際の旋回動作と同じ結果を得ることができ

with cte as (
    select key1, key2, value, 
    row_number() over (partition by key1, key2 order by key2) as key2_rn 
    from mytable 
) 
select key1, max(val1_val) over (partition by key1) as val1, val2_val as val2 
from cte 
pivot (max(value) as val for (key2) in ('val1' as val1, 'val2' as val2)); 

これらもkey2値の固定数があることを前提。それが2つ以上の場合は、これを拡張することができます(私は簡単に言うつもりでしたが、どのキーを使用するかによって異なります)。固定された既知のリストがなく、列の数がわからない場合は、既存の複雑さの上に動的SQLを使用する必要があります。

2
select key1, 
     max(case when key2 = 'val1' then value end) as val1 
     max(case when key2 = 'val2' then value end) as val2 
from MyTable 
group by key1 
関連する問題