【发布时间】:2019-08-13 14:16:21
【问题描述】:
我有这张表,它按地区存储容器以及每个容器中咖啡袋的数量。
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 个咖啡袋)的容器 ID。供应过剩是可以的。
这是我提出的问题
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
问题:
- 是否有更好、更优化的方法来实现这一目标?
- 特别是 Container 表是非常大的表,我认为子查询 sq1 将不必要地计算该区域中所有容器的 RunningTotals。我想知道一旦 RunnningTotal 超过 @RequiredCoffeePouches 是否有任何方法让 sq1 停止处理更多行。
【问题讨论】:
-
一般来说停止是不安全的。运行总数可以以负值下降和上升。但即使它们被限制为积极的 SQL Server 仍然不会为您执行此操作。您可以在这里运行两次查询stackoverflow.com/a/53971884/73226
标签: sql sql-server tsql sql-server-2014