我有一个关于运行总计的问题,我知道有几种方法。但是,我对其进行了轻微修改,并且正在努力寻找正确的方法。
所以我有订单,每个订单都有其唯一的 ID 和数量。数量可以上升(买入)和下降(卖出)。ID 按顺序排列,但并不“密集”,因此两个后续订单之间可能存在间隙。我需要选择所有代表最早位置的订单。位置是连续的订单范围,总和为0,例如(id,qty):(1,1)(2,2)(3,-3)(4,1)(5,-1)-有两个位置,最早的位置由 ID 为 1、2、3 的订单组成。
我目前的做法:
架构
CREATE TABLE [dbo].[orders](
[id] [int] NULL,
[qty] [int] NULL
) ON [PRIMARY]
解决方案
create table #or (id int, qty int, rn int)
create clustered index ix_orid on #or(rn)
insert into #or
select *, ROW_NUMBER() over(order by id) as rn from dbo.orders;
with position as (
select o1.*, o1.qty as s from #or o1 where rn = 1
union all
select o1.id, o1.qty, o1.rn, o1.qty + position.s
from #or o1
join position
on o1.rn = position.rn + 1
where position.s > 0
)
select * from position
option (maxrecursion 0)
drop table #or
我担心的是我为所有订单创建了大的临时表。并且所有时间都用于创建这张表。我在 dbo.orders 中有大约 ~3.000.000 行,而结果集是 ~15.000。我目前的想法是限制插入#或使用合理数量的顶部提示,并运行几次直到我们完成。但我想知道它是否可以更容易地完成?
正如评论中所建议的,我可以通过观察运行总数变为零来获取单个位置的订单的最新 ID。然后我可以选择范围内的订单