У меня есть эта таблица, в которой хранятся контейнеры по регионам и количеству кофейных мешочков в каждом контейнере.
if object_id( 'dbo.Container' ) is not null
drop table dbo.Container
go
create table dbo.Container
(
Id int not null,
Region int not null,
NumberOfCoffeePouches int not null,
constraint pkc_Container__Id primary key clustered(Id asc)
)
go
insert into dbo.Container
( Id , Region , NumberOfCoffeePouches )
values
( 1, 1, 10 ),
( 2, 1, 30 ),
( 3, 1, 5),
( 4, 1, 7),
( 5, 1, 1),
( 6, 1, 3),
( 7, 2, 4),
( 8, 2, 4),
( 9, 2, 4)
Мне нужно перечислить идентификаторы контейнеров, которые будут использоваться для выполнения заказа, скажем, 50 кофейных пакетиков.Переполнение - это нормально.
Вот запрос, который я сформулировал
declare @RequiredCoffeePouches int = 50
select
sq2.Id,
sq2.NumberOfCoffeePouches,
sq2.RunningTotal,
sq2.LagRunningTotal
from
(
select
sq1.Id,
sq1.NumberOfCoffeePouches,
sq1.RunningTotal,
lag(sq1.RunningTotal, 1, 0) over (order by sq1.Id asc)
as 'LagRunningTotal'
from
(
select
c.Id,
c.NumberOfCoffeePouches,
sum(c.NumberOfCoffeePouches)
over (order by c.Id asc) as 'RunningTotal'
from
dbo.Container as c
where
c.Region = 1
) as sq1
) as sq2
where
sq2.LagRunningTotal <= @RequiredCoffeePouches
Он дает ожидаемый результат
Id NumberOfCoffeePouches RunningTotal LagRunningTotal
----------- --------------------- ------------ ---------------
1 10 10 0
2 30 40 10
3 5 45 40
4 7 52 45
Вопрос:
- Есть ли лучший и более оптимизированный способ достижения этого?
- Специально таблица «Контейнер» - это очень большая таблица, и я думаю, что подзапрос sq1 излишне вычислит значения RunningTotals для всех контейнеров в регионе.Мне было интересно, есть ли в любом случае sq1 перестать обрабатывать больше строк, как только RunnningTotal превысит @ RequiredCoffeePouches.