如何使用以下数据在Dynamic 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 :(得分:1)
您的查询存在的问题是,透视查询没有要分组的列。 pivot
表运算符会自动GROUP BY
来自锚点查询的部分MAX(Designation) FOR AssignmentMonth IN ...
中未列出的列,因此在您的查询中,您只有两列来自锚定查询Designation
和AssignmentMonth
,因此您的查询没有任何额外的列可以分组,以便它为您提供只有一行的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 :(得分: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