Ponieważ korzystasz z SQL Server 2012... oto wersja, która to wykorzystuje. Może to być szybsze niż inne rozwiązania, ale musisz to przetestować na swoich danych.
sum() over()
wykona sumę bieżącą uporządkowaną według Id
dodanie 1
gdy w kolumnie znajduje się wartość i zachowanie bieżącej wartości dla null
wartości. Obliczona suma bieżąca jest następnie używana do podziału wyniku w first_value() over()
. Pierwsza wartość uporządkowana według Id
dla każdej „grupy” wierszy wygenerowanych przez sumę bieżącą ma żądaną wartość.
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
Coś, co będzie działać przed 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