您可以使用遞歸CTE來計算運行總和。
declare @Sales table (PKId int, Qty int)
insert into @Sales values
(1, 100),
(2, 200),
(3, 750),
(4, 200)
declare @TotalMaxQty int = 1000
;with OrderedSales as
(
select PKId,
Qty,
row_number() over(order by PKId) as rn
from @Sales
--where "some where clause against Sales"
),
RunningSum as
(
select OS.PKId,
case when OS.Qty < @TotalMaxQty then OS.Qty
else @TotalMaxQty
end as Qty,
@TotalMaxQty - OS.Qty as Rest,
OS.rn
from OrderedSales OS
where rn = 1
union all
select OS.PKId,
case when OS.Qty < RS.Rest then OS.Qty
else RS.Rest
end as Qty,
RS.Rest - OS.Qty,
OS.rn
from OrderedSales as OS
inner join RunningSum as RS
on OS.rn = RS.rn + 1
where RS.Rest > 0
)
select PKId,
Qty
from RunningSum
option (maxrecursion 0)
編輯:存儲在表變量的有序銷售與rn
作爲主鍵的版本。我的測試顯示性能大大提高。
declare @Sales table (PKId int, Qty int)
insert into @Sales values
(1, 100),
(2, 200),
(3, 750),
(4, 200)
declare @TotalMaxQty int = 1000
declare @OrderedSales table
(
rn int primary key,
PKId int,
Qty int
)
insert into @OrderedSales
select row_number() over(order by PKId),
PKId,
Qty
from @Sales
--where "some where clause against Sales"
;with RunningSum as
(
select OS.PKId,
case when OS.Qty < @TotalMaxQty then OS.Qty
else @TotalMaxQty
end as Qty,
@TotalMaxQty - OS.Qty as Rest,
OS.rn
from @OrderedSales OS
where rn = 1
union all
select OS.PKId,
case when OS.Qty < RS.Rest then OS.Qty
else RS.Rest
end as Qty,
RS.Rest - OS.Qty,
OS.rn
from @OrderedSales as OS
inner join RunningSum as RS
on OS.rn = RS.rn + 1
where RS.Rest > 0
)
select PKId,
Qty
from RunningSum
option (maxrecursion 0)
這基本上是運行總和。您的查詢通常會返回多少行?這將決定三角聯合方法是否可行。 –
@Martin Smith每個查詢不會再有500-800條記錄。 – garik
啊對了。用三角形連接應該不會太差(自己加入'Sales1.PKId