If you need the columns dynamically you have to use dynamic SQL:
IF OBJECT_ID(N'tempdb..#temp', 'U') IS NOT NULL
DROP TABLE #temp;
CREATE TABLE #temp ([Col_Name] CHAR(2) NOT NULL, Col_Order INT NOT NULL, [Row_Number] INT NOT NULL, [Value] VARCHAR(5) NOT NULL);
INSERT #temp([Col_Name], Col_Order, [Row_Number], [Value])
VALUES
('C1', 1, 1, '122'),
('C2', 2, 1, '123'),
('C3', 3, 1, '134'),
('C4', 4, 1, '1423'),
('C1', 1, 2, '12'),
('C2', 2, 2, '324'),
('C3', 3, 2, '124'),
('C4', 4, 2, 'ba');
DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX);
SET @cols = STUFF((SELECT ',' + QUOTENAME(t.[Col_Name])
FROM #temp AS t
GROUP BY t.[Col_Name], t.Col_Order
ORDER BY t.Col_Order
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
set @query = 'SELECT ' + @cols + ' FROM (SELECT [Col_Name], [Row_number], [Value] FROM #temp) x
PIVOT (MAX([Value]) FOR [Col_Name] IN (' + @cols + ')) p; '
EXECUTE sp_executesql @query;
If Row_Number
in your sample data isn't a column, and you actually need to use the ROW_NUMBER()
function, then the principal is still exactly the same, but instead of selecting the column Row_Number
in your dynamic SQL, you would just use the function:
SET @query = 'SELECT ' + @cols + '
FROM (SELECT [Col_Name],
[Row_number] = ROW_NUMBER() OVER(PARTITION BY Col_Name ORDER BY [Row_number]),
[Value]
FROM #temp) x
PIVOT (MAX([Value]) FOR [Col_Name] IN (' + @cols + ')) p; ';