SQL Pivot包含不平衡数据

时间:2016-07-04 13:08:02

标签: sql sql-server tsql pivot aggregate

如果可以“填充”主表中未包含的数据,我将使用Pivot功能。 我的表格包含以下数据:

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

使用Pivot功能

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

这是通过Pivot功能还是以其他方式实现的? 提前谢谢了   约尔格

2 个答案:

答案 0 :(得分:0)

您似乎(有点)想要列中的列表。如果你能忍受这个结果:

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(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()

执行所需操作
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;

请注意,order by中的dense_rank()已更改为按值明确排序。

答案 1 :(得分: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值

,这也会有效