Другой вариант с небольшим XML
Полное раскрытие: Не так эффективно, как у GMB CROSS APPLY
(+1) или UNPIVOT
. НО он динамически отключает практически любую строку, таблицу, представление или произвольный запрос c без фактического использования Dynami c SQL.
Пример
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
Возвращает
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
РЕДАКТИРОВАТЬ - Если интересует здесь подход TVF
Select A.EmpID
,B.*
From @YourTable A
Cross Apply [dbo].[tvf-XML-UnPivot-Row]((Select A.* for XML RAW)) B
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)
)