2016-07-04 78 views
0

如果可以「填滿」未包含在主表中的數據,我正在使用樞軸功能進行剝離。 我的表包含以下數據:SQL與非平衡數據樞軸

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'); 

隨着旋轉功能

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

我COL2只得到一個(最大)值的ObjID = 21:

objID col1   col2   col3 
21 a value  col2_2_x  col3_1 
22 another value col2_2  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 

這可能與樞軸功能或以其他方式? 提前 約爾格

+0

哪些DBMS您使用更值?語法看起來像SQL Server。 –

+0

最後是要爲SQL Server和ORACLE – DickerXXL

回答

0

非常感謝你似乎(在某種程度上)想在列名單。如果你能夠接受這個結果住:

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+採用累積max(),你可以做你想做什麼:

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()中的order by已被更改爲按值顯式排序。

+0

工作很快的答案。謝謝。第二個SQL對ORACLE也有好處:-)。你知道SQL Server 2008的解決方案嗎? – DickerXXL

+0

我想更新此解決方案。 culmulative max()也適用於ORACLE。但現實生活比上面的例子更復雜。在現實生活中,我必須處理超過100個列,而不僅僅是3個。在這種情況下,ORACLE最終在ORA-01467:排序鍵太長:-(但是,好吧,一旦你沒有那麼多的列,它工作正常 – DickerXXL

+0

@DickerXXL ......需要使用100列進行排序似乎很可疑 –

0

使用CTE和左加入擺脫COL1和COL3值都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個列,而不僅僅是3個。在這種情況下,ORACLE消耗大於100 GB的臨時表空間,並且不會在數小時後結果結束:-(但是,如果您沒有,許多列它工作正常 – DickerXXL

+0

@DickerXXL你可以給我們記錄的大小順序,列和不同的objID? – MtwStark