2015-06-21 58 views
0

如何在动态SQL创建一个简单的数据透视表数据如下:简单的数据透视表与月和文本数据动态SQL

ID Month AssignmentMonth Designation 
1 5   May   Joe Blow 
2 5   May   Available 
3 5   May   Available 
4 5   May   Available 
5 6   June  Carry over 
6 6   June  Christopher Freeberg 
7 6   June  Ringo Starr 
8 6   June  Robert L Testcustomer 
9 7   July  Carry over 
10 7   July  Carry over 
11 7   July  Carry over 
12 7   July  Carry over 
13 8   August  Available 
14 8   August  Carry over 
15 8   August  Carry over 
16 8   August  Carry over 

所以当它完成它看起来像下面的例子:

May    June     July     August 

Joe Blow   Carry Over   Carry over   Available 
Available  Christopher Freeburg Carry over   Carry over 
Available  Ringo Starr   Carry over   Carry over 
Available  Robert L Testcustomer Carry over   Carry over 

这是我的尝试,但它确实产生了正确的结果。它只返回一行。

August  July  June     May 
    Carry over Carry over Robert L Testcustomer Joe Blow 

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

    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(AssignmentMonth) 
       from @CardAssigns 
     FOR XML PATH(''), TYPE 
     ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'') 
SET @query = 'WITH PivotData AS 
(
SELECT Designation, AssignmentMonth  
FROM #Temp1 
) 
SELECT '+ @cols +' 
FROM PivotData 
PIVOT 
(
MAX(Designation) 
FOR AssignmentMonth 
IN ('+ @cols +') 
) as PIVOTResult' 

EXECUTE(@query) 

回答

0

下面的示例使用动态查询和ROW_NUMBER按照您所描述的排列值。

CREATE TABLE #Data (
    ID INT, 
    Month INT, 
    AssignmentMonth VARCHAR(50), 
    Designation VARCHAR(50) 

) 
INSERT #Data VALUES 
(1,5,'May','Joe Blow'), 
(2,5,'May','Available'), 
(3,5,'May','Available'), 
(4,5,'May','Available'), 
(5,6,'June','Carry over'), 
(6,6,'June','Christopher Freeberg'), 
(7,6,'June','Ringo Starr'), 
(8,6,'June','Robert L Testcustomer'), 
(9,7,'July','Carry over'), 
(10,7,'July','Carry over'), 
(11,7,'July','Carry over'), 
(12,7,'July','Carry over'), 
(13,8,'August','Available'), 
(14,8,'August','Carry over'), 
(15,8,'August','Carry over'), 
(16,8,'August','Carry over') 

DECLARE @ColumnList VARCHAR(MAX) = 
    SUBSTRING((
     SELECT 
      ',[' + AssignmentMonth + ']' AS [text()] 
     FROM #Data 
     GROUP BY AssignmentMonth 
     ORDER BY MIN(ID) 
     FOR XML PATH('') 
    ), 2, 4000) 
DECLARE @ColumnAggs VARCHAR(MAX) = 
    SUBSTRING((
     SELECT 
      ',MAX([' + AssignmentMonth + ']) AS [' + AssignmentMonth + ']' AS [text()] 
     FROM #Data 
     GROUP BY AssignmentMonth 
     ORDER BY MIN(ID) 
     FOR XML PATH('') 
    ), 2, 4000) 

DECLARE @Sql VARCHAR(MAX) = 
    'SELECT ' + @ColumnAggs + ' FROM (' 
    + 'SELECT ROW_NUMBER() OVER (PARTITION BY Month ORDER BY ID) AS RowId, ' + @ColumnList 
    + 'FROM #Data D PIVOT (MAX(Designation) FOR AssignmentMonth IN (' + @ColumnList + ')) P' 
    + ') T GROUP BY RowId' 
    PRINT @Sql 
EXEC (@Sql) 

输出

May       June       July       August 
------------------------------ ------------------------------ ------------------------------ ------------------------------ 
Joe Blow      Carry over      Carry over      Available 
Available      Christopher Freeberg   Carry over      Carry over 
Available      Ringo Starr     Carry over      Carry over 
Available      Robert L Testcustomer   Carry over      Carry over 
+0

非常感谢。 –

1

与您查询的问题,是枢轴查询没有通过有组列。 pivot表运算符自动GROUP BY列中没有列出的部分MAX(Designation) FOR AssignmentMonth IN ...来自锚查询,因此在您的查询中,只有来自锚查询DesignationAssignmentMonth的两列,因此您的查询不会有任何额外的列分组,以便它给你只有一行的MAX(Designation)。但是,您可以通过添加多个列来进行分组,并且由于您既不能通过ID也不能通过Month进行分组,所以您可以添加行号列,它会为您提供所需的结果,如下所示:

SET @query = 'WITH PivotData AS 
(
    SELECT 
    Designation, 
    AssignmentMonth, 
    ROW_NUMBER() OVER(PARTITION BY AssignmentMonth ORDER BY ID) AS RN 
    FROM CardAssigns 
) 
SELECT '+ @cols +' 
FROM PivotData 
PIVOT 
(
    MAX(Designation) 
    FOR AssignmentMonth 
    IN ('+ @cols +') 
) as PIVOTResult'; 

EXECUTE(@query); 

这会给你:

|  August |  July |     June |  May | 
|------------|------------|-----------------------|-----------| 
| Available | Carry over |   Carry over | Joe Blow | 
| Carry over | Carry over | Christopher Freeberg | Available | 
| Carry over | Carry over |   Ringo Starr | Available | 
| Carry over | Carry over | Robert L Testcustomer | Available | 
+1

优秀和可以理解 – mohan111