2011-03-26 130 views
1

我需要采取一些查询结果并将它们展平以获取报表。转换SQL查询结果

DECLARE @randomTable table (ID int, OtherID int, Val varchar(max)) 

insert into @randomTable(ID, OtherID, Val) 
values (1, 100, 'Some Value 1'), (2, 100, 'Some Other 2'), 
     (3, 100, 'Some Value 3'), (4, 200, 'Some Other 4'), 
     (5, 200, 'Some Value 5'), (6, 300, 'Some Other 6'), 
     (7, 300, 'Some Value 7'), (8, 300, 'Some Other 8'), 
     (9, 400, 'Some Value 9'), (10, 500, 'Some Other 10')    

select OtherID, Val from @randomTable 

结果:

-- 100 | Some Value 1 
-- 100 | Some Other 2 
-- 100 | Some Value 3 
-- 200 | Some Other 4 
-- 200 | Some Value 5 
-- 300 | Some Other 6 
-- 300 | Some Value 7 
-- 300 | Some Other 8 
-- 400 | Some Value 9 
-- 500 | Some Other 10 

是否有一个SQL的方式来改变这种作为选择:

-- 100 | Some Value 1 | Some Other 2 | Some Value 3 
-- 200 | Some Other 4 | Some Value 5 
-- 300 | Some Other 6 | Some Value 7 | Some Other 8 
-- 400 | Some Value 9 
-- 500 | Some Other 10 

注意:上面就是一个例子。我的真实数据不是静态的。此外,在我的真实数据中,OtherID是一个字符串值,Val值是以varbinary存储的图像。

我当然要限制我将允许的列数。我想最多5(在这之后,我很好,失去了额外的行)。

有没有办法做到这一点?

回答

4
;WITH cte 
    AS (SELECT OtherID, 
       Val, 
       ROW_NUMBER() OVER (PARTITION BY OtherID ORDER BY (SELECT 0)) rn 
     FROM @randomTable) 
SELECT OtherID, 
     [1], 
     [2], 
     [3], 
     [4], 
     [5] 
FROM cte PIVOT(MAX(Val) FOR rn IN ([1], [2], [3], [4], [5])) AS PivotTable; 

提供一些解释SELECT * FROM cte将返回以下。

OtherID  Val     rn 
----------- -------------------- --- 
100   Some Value 1   1 
100   Some Other 2   2 
100   Some Value 3   3 
200   Some Other 4   1 
200   Some Value 5   2 
300   Some Other 6   1 
300   Some Value 7   2 
300   Some Other 8   3 
400   Some Value 9   1 
500   Some Other 10  1 

我已经加入了row_number列给一些在PIVOT使用。请注意,每OtherID,rn组合有零或一行。 PIVOT声明相当于以下内容。

SELECT OtherID, 
     MAX(CASE WHEN rn=1 THEN Val END) AS [1], 
     MAX(CASE WHEN rn=2 THEN Val END) AS [2], 
     MAX(CASE WHEN rn=3 THEN Val END) AS [3], 
     MAX(CASE WHEN rn=4 THEN Val END) AS [4], 
     MAX(CASE WHEN rn=5 THEN Val END) AS [5] 
FROM cte 
GROUP BY OtherID /*You want one row per OtherID */ 
+0

这正是我所需要的!谢谢马丁,你很乐意帮助我解决这个问题! – Vaccano 2011-03-27 03:51:09

+1

Martin,非常聪明的使用rn分区! – 2011-03-27 04:18:40

2

林不知道,如果你想枢转到列或连接结果转换成一列(报告)。

如果您正在寻找动态数据透视表,请查看此处的文章:link以及其后的评论。如果你能够限制主轴所涉及的列,你可以使用pivot操作符(如前所述)并获得更好的性能。

如果您希望将行连接到列,请查看下面的查询。利用XML PATH确实会对特殊字符(< &等)产生一些影响,因此如果这适用于您的情况,请回传,我们可以扩展此简单示例。

-- if you have normalized type table use it instead of this cte 
    ;with c_distinct (OtherId) 
    as  ( select distinct OtherId 
       from @randomTable 
      ) 
    select OtherId, 
      stuff(c, 1, 2, '') 
    from c_distinct cd 
    cross 
    apply ( select '| ' + Val 
       from @randomTable rt 
       where cd.OtherId = rt.OtherId 
       for xml path('') 
      ) d(c)