Raz*_*wan 5 sql pivot sql-server-2008-r2
我遇到了一个我无法解决的问题,已经尝试了一切。希望我能在这里得到答案。
我表中的数据如下
Id Month Val1 Val2 Val3
1 Jan 70 80 90
2 Jan 12 13 15
3 Feb 12 67 99
4 March 14 15 17.1
Run Code Online (Sandbox Code Playgroud)
从以下结构中,我想基于列透视数据,val1这样我的输出将类似于:
Jan Jan Feb March
70 12 12 14
Run Code Online (Sandbox Code Playgroud)
我认为您将需要使用动态 SQL(除非您的列保持静态)
需要执行的查询是:
SELECT [Jan] = [Jan1],
[Jan] = [Jan2],
[Feb] = [Feb1],
[March] = [March1]
FROM ( SELECT [PivotColumn] = [Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)),
Val1
FROM T
) t
PIVOT
( MAX(Val1)
FOR [PivotColumn] IN ([Jan1], [Jan2], [Feb1], [March1])
) pvt
Run Code Online (Sandbox Code Playgroud)
虽然我不确定为什么会这样
Jan Jan Feb March
70 12 12 14
Run Code Online (Sandbox Code Playgroud)
并不是
Jan Jan Feb March
12 70 12 14
Run Code Online (Sandbox Code Playgroud)
所以你可能需要修改函数ORDER BY中的ROW_NUMBER。
要动态构建它,您可以使用:
-- CREATE SAMPLE TABLE AND INSERT DATA
CREATE TABLE #T (ID INT, Month VARCHAR(10), Val1 INT, Val2 INT, Val3 DECIMAL(5, 1));
INSERT #T VALUES (1, 'Jan', 70, 80, 90), (2, 'Jan', 12, 13, 15), (3, 'Feb', 12, 67, 99), (4, 'March', 14, 15, 17.1);
-- DECLARE VARIABLES TO STORE THE COLUMN NAMES
DECLARE @PivotList NVARCHAR(MAX) = '',
@ColumnList NVARCHAR(MAX) = '';
-- HERE USE ROW_NUMBER() TO UNIQUELY IDENTIFY VALUES FOR MONTHS
-- THIS MEANS JAN: 70 AND JAN: 12 CAN BE IDENTIFIED SEPARATELY LATER, BUT RETAIN THE DUPLICATE COLUMN NAME [Jan]
SELECT @ColumnList = @ColumnList + ', ' + QUOTENAME([Month]) + ' = ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID))),
@PivotList = @PivotList + ', ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)))
FROM #T
ORDER BY ID;
DECLARE @SQL NVARCHAR(MAX) = 'SELECT ' + STUFF(@ColumnList, 1, 2, '') + '
FROM ( SELECT [PivotColumn] = [Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)),
Val1
FROM #T
) t
PIVOT
( MAX(Val1)
FOR [PivotColumn] IN (' + STUFF(@PivotList, 1, 2, '') + ')
) pvt';
EXECUTE SP_EXECUTESQL @SQL;
DROP TABLE #T;
Run Code Online (Sandbox Code Playgroud)
同样,意志中的任何更改ROW_NUMBER也需要反映在ORDER BY生成列名称和数据透视表的查询中的子句中:
SELECT @ColumnList = @ColumnList + ', ' + QUOTENAME([Month]) + ' = ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID))),
@PivotList = @PivotList + ', ' + QUOTENAME([Month] + CONVERT(VARCHAR(10), ROW_NUMBER() OVER(PARTITION BY [Month] ORDER BY ID)))
FROM #T
ORDER BY ID;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
21445 次 |
| 最近记录: |