formally, your task is not to transpose in a mathematical sense, but to create a pivot table. For these purposes in TSQL there is a PIVOT operator (as well as the reverse UNPIVOT ).
Unfortunately, this operator does not work with a dynamic set of columns. Therefore, for such cases, you have to build a query as a string and then execute it. What in general does not quite fit your task of creating a view ( view ). Therefore, you can count on stored procedures.
Initial data
create table #t (item varchar(10), value int); INSERT INTO #t VALUES ('item1', 5), ('item1', 6), ('item2', 7),('item3', 8),('item2', 9);
Columns, as you have already written, we collect dynamically in a row. For all this, we define several variables (here @maxN is the number of result columns):
DECLARE @maxN int = (select top 1 count(value) from #t group by item order by count(value) desc); DECLARE @n int = 1; DECLARE @nStr VARCHAR(3); DECLARE @strSel varchar(1024) = '', @strFor varchar(512) = '', @sql nvarchar(MAX) = '';
Dynamically form lines in a loop:
WHILE (@n <= @maxN) BEGIN SET @nStr = cast(@n as nvarchar); SET @strSel += ',[' + @nStr + ']' + ' as col' + @nStr; SET @strFor += (case when @n > 1 then ',' else '' end) + '[' + @nStr + '] '; SET @n += 1; END;
Next, glue everything into a SQL query string and complete it.
SET @sql = 'SELECT pt.item' + @strSel + ' FROM ( select item, value, row_number() over (partition by item order by value) as colIdx from #t ) as data PIVOT ( SUM(data.value) FOR colIdx in (' + @strFor + ') ) as pt'; print @sql; execute sp_executesql @sql; drop table #t;
The request received is as follows:
SELECT pt.item,[1] as col1,[2] as col2 FROM ( select item, value, row_number() over (partition by item order by value) as colIdx from #t ) as data PIVOT ( SUM(data.value) FOR colIdx in ([1] ,[2]) ) as pt
And the results of its implementation:
item col1 col2 ---------- ----------- ----------- item1 5 6 item2 7 9 item3 8 NULL
PIVOTin the end? If not, he will solve your problem. It if you slip a line of request, then you will not make in any way, only. - teran