2016-07-04 5 views
0

メインテーブルに含まれていないデータを "補充する"ことができる場合は、ピボット機能を使用しています。アンバランスデータを使用したSQLピボット

objID col1   col2   col3 
21 a value  col2_2_x  col3_1 
22 another value col2_2  col3_2 

は、私が好きなもの:ピボット機能

select 
* 
from (
select 
    objID 
, colID 
, value 
from tmpData) 
t 
PIVOT (MAX(value) for colID in ([col1], [col2], [col3])) pivottable; 

私はCOL2でのObjID = 21 1つだけ(最大)値を取得して

create table tmpData (objID INT, colID varchar(5), value varchar(50)); 
insert into tmpData (objId, colId, value) values(21, 'col1', 'a value'); 
insert into tmpData (objId, colId, value) values(21, 'col2', 'col2_1'); 
insert into tmpData (objId, colId, value) values(21, 'col2', 'col2_2_x'); -- a second 'value' for col_2 
insert into tmpData (objId, colId, value) values(21, 'col3', 'col3_1'); 
insert into tmpData (objId, colId, value) values(22, 'col1', 'another value'); 
insert into tmpData (objId, colId, value) values(22, 'col2', 'col2_2'); 
insert into tmpData (objId, colId, value) values(22, 'col3', 'col3_2'); 

: 私のテーブルには、これらのデータを含んでいます取得するすべての値があり、col1とcol3のobjID = 21の指定されていないデータを入力します。

objID col1   col2  col3 
21 a value  col2_2  col3_1 
21 a value  col2_2_x col3_1 
22 another value col2_2  col3_2 

これはPivot機能や他の方法で可能ですか? 事前に感謝します Joerg

+0

あなたが使用しているDBMSのためのより多くの価値を持っている場合、これはまた、動作するためにcol1とcol3というの値を取得するために参加しますか?構文はSQL Serverのように見えます。最後に –

+0

はSQL ServerとORACLEのために働く必要があります – DickerXXL

答えて

0

あなたは(並べ替え)列内のリストを希望しているようです。あなたはこのような結果と一緒に暮らすことができる場合:累積max()を使用して

select objId, 
     max(case when colId = 'col1' then value end) as col1, 
     max(case when colId = 'col2' then value end) as col2, 
     max(case when colId = 'col3' then value end) as col3 
from (select d.*, 
      dense_rank() over (partition by objId, colId order by (select NULL)) as seqnum 
     from tmpData d.* 
    ) t 
group by objId, seqnum; 

SQL Serverの2012+では、あなたがやりたいことができますが:

objID col1   col2  col3 
21 a value  col2_2  col3_1 
21 NULL   col2_2_x NULL 
22 another value col2_2  col3_2 

はその後、値を列挙することにより、これを行うことができます

select objId, 
     max(max(case when colId = 'col1' then value end)) over (partition by objId order by seqnum) as col1, 
     max(max(case when colId = 'col2' then value end)) over (partition by objId order by seqnum) as col2, 
     max(max(case when colId = 'col3' then value end)) over (partition by objId order by seqnum) as col3 
from (select d.*, 
      dense_rank() over (partition by objId, colId order by (select value)) as seqnum 
     from tmpData d.* 
    ) t 
group by objId, seqnum; 

dense_rank()のが明示的に値順に変更されていることに注意してください。

+0

非常に迅速な答え。ありがとう。 2番目のSQLはORACLEのトリックも行います:-) SQL Server 2008のソリューションをご存じですか? – DickerXXL

+0

私はこの解決策を更新したい。 culmulative max()もORACLEで動作しています。しかし、実際の人生は上記の例よりも複雑です。実際の生活では、私は100以上の列を扱う必要があります。この場合、ORACLEはORA-01467で終わります。ソート・キーが長すぎます:-(ただし、一度はそれほど多くの列を持たないとうまくいきません – DickerXXL

+0

@DickerXXL。。並べ替えに100列を使用すると疑わしいようです。 –

0

利用CTEと左には、すべてのcol2の値

;with 
t as (select distinct objID from #tmpData), 
t1 as (select objID, value col1 from #tmpData where colID = 'col1'), 
t2 as (select objID, value col2 from #tmpData where colID = 'col2'), 
t3 as (select objID, value col3 from #tmpData where colID = 'col3') 
select t.objID, col1, col2, col3 
from t 
left join t1 on t.objID = t1.objID 
left join t2 on t.objID = t2.objID 
left join t3 on t.objID = t3.objID 
order by t.objID 

あなたがcol1のか、col3という

+1

このソリューションを更新したいのですが、「自己結合」もORACLEでも機能していますが、実際の生活は上記の例より複雑です。実際の人生私は100以上の列を処理する必要があります。この場合、ORACLEは> 100 GBの一時表領域を消費し、数時間後の結果では終わりません:-(しかし、OK多くの列は正常に動作しています。 – DickerXXL

+0

@DickerXXLは、列と別個のobjIDのレコードの大きさの順序を教えてください。 – MtwStark

関連する問題