Тъй като сте на SQL Server 2012... ето версия, която използва това. Може да е по-бързо от други решения, но трябва да тествате това върху данните си.
sum() over()
ще направи текуща сума, подредена по Id
добавяне на 1
когато има стойност в колоната и запазване на текущата стойност за null
стойности. След това изчислената текуща сума се използва за разделяне на резултата в first_value() over()
. Първата стойност, подредена по Id
за всяка "група" от редове, генерирани от текущата сума, има желаната от вас стойност.
select T.Id,
first_value(T.FeeModeId)
over(partition by T.NF
order by T.Id
rows between unbounded preceding and current row) as FeeModeId,
first_value(T.Name)
over(partition by T.NS
order by T.Id
rows between unbounded preceding and current row) as Name,
T.Amount
from (
select Id,
FeeModeId,
Name,
Amount,
sum(case when FeeModeId is null then 0 else 1 end)
over(order by Id) as NF,
sum(case when Name is null then 0 else 1 end)
over(order by Id) as NS
from YourTable
) as T
Нещо, което ще работи преди SQL Server 2012:
select T1.Id,
T3.FeeModeId,
T2.Name,
T1.Amount
from YourTable as T1
outer apply (select top(1) Name
from YourTable as T2
where T1.Id >= T2.Id and
T2.Name is not null
order by T2.Id desc) as T2
outer apply (select top(1) FeeModeId
from YourTable as T3
where T1.Id >= T3.Id and
T3.FeeModeId is not null
order by T3.Id desc) as T3