Вот вариант, где мы разворачиваем данные и затем применяем условное агрегирование в CROSS APPLY
Пример
Declare @YourTable Table ([A] varchar(50),[B] varchar(50),[C] varchar(50),[D] varchar(50),[E] varchar(50))
Insert Into @YourTable Values
(1,2,3,NULL,NULL)
,(NULL,4,NULL,5,NULL)
,(NULL,null,6,7,8)
,(9,NULL,NULL,NULL,NULL)
Select A.*
,B.*
From @YourTable A
Cross Apply (
Select Val1 = max(case when ColNr=1 then Value end)
,Val2 = max(case when ColNr=2 then Value end)
,Val3 = max(case when ColNr=3 then Value end)
From (
Select ColNr = row_number() over (order by Seq)
,B1.*
From (values (1,A)
,(2,B)
,(3,C)
,(4,D)
,(5,E)
) B1(Seq,Value)
Where Value is not null
) B2
) B
Возвращает
![enter image description here](https://i.stack.imgur.com/78wrM.png)
Просто для удовольствия, вот XML версия
Select A.*
,Val1 = XMLData.value('/x[1]','varchar(max)')
,Val2 = XMLData.value('/x[2]','varchar(max)')
,Val3 = XMLData.value('/x[3]','varchar(max)')
From @YourTable A
Cross Apply ( values ( convert(xml,
concat('<x>'+A+'</x>'
,'<x>'+B+'</x>'
,'<x>'+C+'</x>'
,'<x>'+D+'</x>'
,'<x>'+E+'</x>'
) ) ) ) B(XMLData)