Reputation: 2140
I have a SQL Server table which I'd like to transpose, i.e. switch the rows and columns.
The original table looks like this:
empname empqual emprank empexp
Lily MASTERS 1 9
Sasha UNIVERSITY 1 9
Harry UNIVERSITY 1 9
Angela MASTERS 4 10
Joyce UNIVERSITY 5 11
Please note that the row data is dynamic and the above table is just to demonstrate the table schema.
EDIT: I'd like to modify the above table so that it looks like this:
DETAILS Column1 Column2 Column3 Column4 Column5
empname Lily Sasha Harry Angela Joyce
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
I have looked through several online examples. The PIVOT
function seems to be the most commonly-used function when tables are transposed, but since the operation I require doesn't involve any aggregations, unlike most other examples, I do not know how to do this. Apologies if this question is redundant and a possible answer already exists elsewhere.
Upvotes: 1
Views: 1418
Reputation: 18411
You may check at this Fiddle
EDIT
I made it dynamic...
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
SET @cols = STUFF((SELECT distinct ',' + 'Column' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname))
FROM Table1 c
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SET @query = '
SELECT 1 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empname) as e,
''empname'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 2 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empqual) as e,
''empqual'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 3 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,emprank) as e,
''emprank'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
UNION
SELECT 4 as OrderBy,
*
FROM
(
SELECT ''Column'' + CONVERT(VARCHAR,Row_Number() OVER (Order By empname)) AS Columns,
CONVERT(VARCHAR,empexp) as e,
''empexp'' AS Details
FROM Table1
) p
PIVOT
(
MAX (e)
FOR Columns IN
(
' + @cols + ' )
) as pvt
order by OrderBy'
EXECUTE (@query)
Giannis
Upvotes: 1
Reputation: 239646
This query works for your sample data:
declare @t table(
empname varchar(20) not null,
empqual varchar(20) not null,
emprank int not null,
empexp int not null
)
insert into @t(empname,empqual,emprank,empexp) values
('Lily','MASTERS',1,9),
('Sasha','UNIVERSITY',1,9),
('Harry','UNIVERSITY',1,9),
('Angela','MASTERS',4,10),
('Joyce','UNIVERSITY',5,11)
select *
from (select empname,empqual,CONVERT(varchar(20),emprank) as emprank,CONVERT(varchar(20),empexp) as empexp from @t) t
unpivot (value FOR measure in (empqual,emprank,empexp)) as unpvt
pivot (MAX(value) for empname in (Lily,Sasha,Harry,Angela,Joyce)) pvt
order by
CASE measure WHEN 'empqual' THEN 0
WHEN 'emprank' THEN 1
WHEN 'empexp' THEN 2
END
Result:
measure Lily Sasha Harry Angela Joyce
------------ -------------------- -------------------- -------------------- -------------------- --------------------
empqual MASTERS UNIVERSITY UNIVERSITY MASTERS UNIVERSITY
emprank 1 1 1 4 5
empexp 9 9 9 10 11
If your comment about "row data is dynamic" means that you have an unknown list of names, then you'll need to write a query that obtains the list of names first, and then builds the above query using that list of names in the PIVOT
section.
A simple search for "dynamic pivot" should find plenty of examples of doing so.
Upvotes: 0