我尝试在本网站上提出其他几条建议,但由于某些原因,我不能做这项工作。
基本上我正试图从这个任务表中获取:
| TaskID | ProjectID | TaskType | TaskDate1 | TaskDate2 |
---------------------------------------------------------
| 1 | 1 | Type4 | 20130401 | 20130506 |
| 2 | 1 | Type0 | 20130412 | 20130508 |
| 3 | 1 | Type2 | 20130420 | 20130517 |
那个:
| ProjectID | Type0Date1 | Type0Date2 | Type2Date1 | Type2Date2 | Type4Date1 | Type4Date2 |
---------------------------------------------------------
| 1 | 20130412 | 20130508 | 20130420 | 20130517 | 20130401 | 20130506 |
每个项目必须具有多个预定义任务(由其类型标识)。这些任务有很多属性,但我对2个日期感兴趣,每个项目将它们全部放在一行会很好。
我可以轻松地将其转移到以下列之一:PIVOT (MAX(TaskDate1) FOR TaskType IN ([Type0],[Type2],[Type4]))
我尝试复制TaskType列并为TaskDate2围绕它做另一个转轴,但这不会给我一行。
我也无法理解如何将表格首先转移到我需要的位置,就像其他一些帖子中提出类似问题的建议一样。
如果有一种可扩展的方法(如旋转甚至更多的列),那么很高兴知道。
感谢。
答案 0 :(得分:1)
您可以获得所需的结果,但由于您需要在多列(TaskDate1
和TaskDate2
上进行PIVOT),我首先将两列拆分为多行。
由于您使用的是SQL Server 2008+,因此可以使用UNPIVOT函数或CROSS APPLY来转换多列。基本语法为:
select projectid,
col = TaskType+col,
value
from yourtable
cross apply
(
values
('Date1', TaskDate1),
('Date2', TaskDate2)
) c(col, value)
见SQL Fiddle with Demo。这会将您的数据转换为易于使用的格式:
| PROJECTID | COL | VALUE |
|-----------|------------|------------------------------|
| 1 | Type4Date1 | April, 01 2013 00:00:00+0000 |
| 1 | Type4Date2 | May, 06 2013 00:00:00+0000 |
| 1 | Type0Date1 | April, 12 2013 00:00:00+0000 |
| 1 | Type0Date2 | May, 08 2013 00:00:00+0000 |
获得此格式的数据后,您可以将PIVOT函数应用于获取每个max(value)
的{{1}}:
col
如果每个select projectId,
Type0Date1, Type0Date2,
Type2Date1, Type2Date2,
Type4Date1, Type4Date2
from
(
select projectid,
col = TaskType+col,
value
from yourtable
cross apply
(
values
('Date1', TaskDate1),
('Date2', TaskDate2)
) c(col, value)
) d
pivot
(
max(value)
for col in (Type0Date1, Type0Date2, Type2Date1, Type2Date2,
Type4Date1, Type4Date2)
) piv;
的值数量有限,则上述版本将运行良好,但如果每个项目的任务数量未知,则需要使用动态SQL来获得最终结果:
ProjectId
见SQL Fiddle with Demo。这些将产生结果:
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT ',' + QUOTENAME(TaskType+col)
from yourtable
cross apply
(
select 'Date1', 1 union all
select 'Date2', 2
) c(col, so)
group by col, tasktype, so
order by tasktype, so
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT projectid, ' + @cols + '
from
(
select projectid,
col = TaskType+col,
value
from yourtable
cross apply
(
values
(''Date1'', TaskDate1),
(''Date2'', TaskDate2)
) c(col, value)
) x
pivot
(
max(value)
for col in (' + @cols + ')
) p '
execute sp_executesql @query