2013-10-16 542 views
0

我有这样的一个表:PIVOT在SQL表

Value   Name 

ProjectA  ProjectName 
10/10/2012  StartDate 
10/10/2013  EndDate 
ProjectB  ProjectName 
11/11/2012  StartDate 
11/11/2013  EndDate 
ProjectC  ProjectName 
12/12/2012  StartDate 
12/12/2013  EndDate 

我需要改变表为:

Project Name   Start Date   End Date 

ProjectA    10/10/2012   10/10/2013 
ProjectB    11/11/2012   11/11/2013 
ProjectC    12/12/2012   12/12/2013 

我用下面的查询来实现我的结果,

select * from Project 
pivot 
(
max(Value) 
for[Name] in ([Project Name],[Start Date],[End Date]) 
)piv 

一旦我执行此操作,我只是得到如下结果:

Project Name  Start Date  End Date 

    Project C   12/12/2012 12/12/2013 

我在查询中犯了什么错误?

回答

2

这个问题与Max(Value)有关,它只会返回最高值,Pivot并不是真的设计用来做非聚合值。

但是这应该解决您的问题。

WITH CTE(Value, Name,RID) 
    AS 
    (
    SELECT Value, Name, ROW_NUMBER() OVER (PARTITION BY (Name)ORDER BY Value) AS RID FROM YOURTABLE --Replace 
    ) 
    SELECT [ProjectName],[StartDate],[EndDate] 
    FROM 
    (SELECT Value,Name,RID 
    FROM CTE)C 
    PIVOT 
    (
    max(Value) 
    FOR Name IN ([ProjectName],[StartDate],[EndDate]) 
    ) AS PivotTable; 

它在我的实例在这里与您的测试数据一起工作。

编辑:动态请求

我不使用动态SQL好,我无法获得列正确排序,虽然这仅仅是由于它的方式组倒序的列名。

DECLARE @columns NVARCHAR(MAX), @sql NVARCHAR(MAX); 
SET @columns = N''; 
SELECT @columns += N'' + QUOTENAME(Name) + ', ' 
    FROM TestTable 
    GROUP BY Name 

Set @columns = LEFT(@Columns,Len(@Columns) -1) 
Print @columns 

SET @sql = N' 
WITH CTE(Value, Name,RID) 
AS 
(
SELECT Value, Name, ROW_NUMBER() OVER (PARTITION BY (Name) ORDER BY Value) AS RID FROM TestTable 
) 
SELECT ' + @columns + ' 
FROM 
(SELECT Value,Name,RID 
FROM CTE)C 
PIVOT 
(
max(Value) 
FOR Name IN (' + @columns + ') 
) AS PivotTable;'; 
PRINT @sql; 
EXEC sp_executesql @sql; 
+0

谢谢你Peter .. – Xavier

+0

如何为动态列实现同样的功能.. – Xavier