将数据转置为多列

4
我有很多客户,每个客户都有67条记录。 每条记录包含活动、日期、ID、标志和许多其他列。 我希望将活动名称作为标题,日期放在这些活动标题下面。 我正在尝试使用下面的表格进一步解释。这是当前的输出:
Client  Activity    Date 
1       A           21/15
1       B           5/5/2012
1       C           51/3115
1       D           54/6/84
2       A           8/6/99
2       B           1/1/2011
2       C           8/4
2       D           9/81/1
3       A           6/51/8
3       B           1/61/8
3       C           1/31
3       D           3/2/1

And I would like it to be:

Client      A       B         C         D
1           21/15   5/5/2012  51/31/15  54/6/84
2           8/6/99  1/1/2011  8/4       9/81/1
3           6/51/8  1/61/8    1/31      3/2/1

可能是Get ROWS as COLUMNS (SQL Server dynamic PIVOT query)的重复问题。 - RichardTheKiwi
1个回答

5
你需要使用PIVOT函数来完成此操作。如果您知道要转换的列数,则可以通过静态透视进行硬编码:
select *
from
(
  select client, activity, dt
  from yourtable
) x
pivot
(
  max(dt)
  for activity in ([A], [B], [C], [D])
) p

请参考带演示的SQL Fiddle

如果你有未知数量的列,则使用动态版本:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(activity) 
                    from yourtable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT client,' + @cols + ' from 
             (
              select client, activity, dt
              from yourtable
            ) x
            pivot 
            (
                max(dt)
                for activity in (' + @cols + ')
            ) p '

execute(@query)

请查看带演示的SQL Fiddle

最后,这也可以通过使用 CASE 语句和聚合函数来完成(请查看带演示的SQL Fiddle):

select client,
  max(case when activity = 'A' then dt end) as A,
  max(case when activity = 'B' then dt end) as B,
  max(case when activity = 'C' then dt end) as C,
  max(case when activity = 'D' then dt end) as D
from yourtable
group by client

感谢您提供的第二个选项。对我非常有帮助。 - dbinott

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接