Reputation: 227
I have a table with basic employee details as below:
Table: tblEmployees
EmpID Name Contact Sex
100 John 55555 M
200 Kate 44444 F
300 Sam 88888 M
I would like to get my query result as follows of a particular employee where EmpID = 200
Col1 Col2
EmpID 200
Name Kate
Sex F
Upvotes: 0
Views: 532
Reputation: 81990
Another option is with a little XML
Full Disclosure: Not as performant as GMB's CROSS APPLY
(+1) or UNPIVOT
. BUT it will dynamically unpivot virtually any row, table, view or ad-hoc query without actually using dynamic SQL.
Example
Declare @YourTable Table ([EmpID] varchar(50),[Name] varchar(50),[Contact] varchar(50),[Sex] varchar(50)) Insert Into @YourTable Values
(100,'John',55555,'M')
,(200,'Kate',44444,'F')
,(300,'Sam',88888,'M')
Select A.EmpID
,C.*
From @YourTable A
Cross Apply ( values (convert(xml,(select a.* for XML Raw ))) ) B(XMLData)
Cross Apply (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From XMLData.nodes('//@*') xNode(xAttr)
Where xAttr.value('local-name(.)', 'varchar(100)') not in ('EmpID','Other','Columns2Exclude')
) C
Returns
EmpID Item Value
100 Name John
100 Contact 55555
100 Sex M
200 Name Kate
200 Contact 44444
200 Sex F
300 Name Sam
300 Contact 88888
300 Sex M
EDIT - If Interested Here a TVF approach
Select A.EmpID
,B.*
From @YourTable A
Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML RAW)) B
The TVF
CREATE FUNCTION [dbo].[tvf-XML-UnPivot-Row](@XML xml)
Returns Table
As
Return (
Select Item = xAttr.value('local-name(.)', 'varchar(100)')
,Value = xAttr.value('.','varchar(max)')
From @XML.nodes('//@*') xNode(xAttr)
)
Upvotes: 0
Reputation: 1836
Or a less sophisticated solution involving 3 UNIONs, assuming the field names are predetermined in advance. This might perform better on large tables. If you have performance issues, analyze the execution plan and make sure indexes are utilized optimally.
Since you are only looking for one particular employee at a time:
SELECT 'empid', convert(varchar(12), EmpID)
FROM tblEmployees
WHERE EmpID = 200
UNION ALL
SELECT 'name', name
FROM tblEmployees
WHERE EmpID = 200
UNION ALL
SELECT 'sex', sex
FROM tblEmployees
WHERE EmpID = 200
The first line does convert(varchar(12)
under the assumption that EmpID is an int
field.
Upvotes: 0
Reputation: 222582
You can use cross apply:
select t.*
from employees e
cross apply (values
('empid', cast(empid as varchar(100))),
('name', name),
('sex', sex)
) t(attr, value)
where e.empid = 200
Presumably, empid
is a number, so explicit casting is needed (otherwise sql server will try to cast the name and sex to numbers, which will fail).
attr | value :---- | :---- empid | 200 name | Kate sex | F
Upvotes: 5