私が考えていた動的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
なぜそれが必要なのかはわかりませんが
Jan Jan Feb March
70 12 12 14
そしてそうではない
Jan Jan Feb March
12 70 12 14
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;
ここでも、列名とピボット リストを生成するクエリ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;