I want to say another way rather than using pivot or unpivot, you can do it with dynamic sql also, it does not matter how many rows or columns the table has, lets check together:
Schema:
create table tblSO(Col1 int, Col2 int, Col3 int, Col4 int)
insert into tblSO values
(1, 2, 3, 3),
(2, 23, 4, 7),
(3, 3 , 12, 4);
now with using row_number and a temptable (or table variable) within dynamic sql you can achieve the result you want:
declare @counter int = 1
declare @counter2 int
set @counter2=(select count(*) from tblSO)
declare @Sql varchar(max)='create table #rotate (colname varchar(20) '
while @counter<=@counter2
begin
set @Sql=@Sql+', val_'+cast(@counter as varchar)+' int'
set @counter=@counter+1
end
set @counter =1
set @Sql=@Sql+');
insert into #rotate(colname)
values (''Col1''),(''Col2''),(''Col3''),(''Col4'');
'
set @Sql = @Sql + '
create table #cte(col1 int,col2 int,col3 int,col4 int,rn int)
insert into #cte
select col1,col2,col3,col4,
row_number() over(order by Col1) rn
from tblSO;
'
while @counter<=@counter2
begin
declare @cl varchar(50)=cast(@counter as varchar)
set @Sql=@Sql + '
update #rotate set val_'+@cl+'=
(select col1 from #cte where rn='+@cl+') where colname=''Col1''
update #rotate set val_'+@cl+'=
(select col2 from #cte where rn='+@cl+') where colname=''Col2''
update #rotate set val_'+@cl+'=
(select col3 from #cte where rn='+@cl+') where colname=''Col3''
update #rotate set val_'+@cl+'=
(select col4 from #cte where rn='+@cl+') where colname=''Col4'' '
set @counter=@counter+1
end
set @Sql=@Sql + ' select * from #rotate
drop table #rotate
drop table #cte'
exec(@Sql)
Output:
Col1 1 2 3
Col2 2 23 3
Col3 3 4 12
Col4 3 7 4