计算负载并避免游标

Sco*_*ton 12 sql sql-server

给出下面的表结构,其表示乘客乘坐有门传感器上下车的公交路线.并且,有一个人坐在那辆公共汽车上,带有一个包含点数的剪贴板.

CREATE TABLE BusLoad(
ROUTE CHAR(4) NOT NULL,
StopNumber INT NOT NULL,
ONS INT,
OFFS INT,
SPOT_CHECK INT)
go
INSERT BusLoad VALUES('AAAA', 1,   5,   0,    null)
INSERT BusLoad VALUES('AAAA', 2,   0,   0,    null)
INSERT BusLoad VALUES('AAAA', 3,   2,   1,    null)
INSERT BusLoad VALUES('AAAA', 4,   6,   3,    8)
INSERT BusLoad VALUES('AAAA', 5,   1,   0,    null)
INSERT BusLoad VALUES('AAAA', 6,   0,   1,    7)
INSERT BusLoad VALUES('AAAA', 7,   0,   3,    null)
Run Code Online (Sandbox Code Playgroud)

我想在此表中添加一列"LOAD",用于计算每个站点的负载.

Load =上一次停止加载+当前停止ONS - 如果SPOT_CHECK为空,则当前停止OFFS,否则为LOAD = SPOT_CHECK

预期成绩:

ROUTE   StopNumber  ONS OFFS    SPOT_CHECK  LOAD
AAAA    1           5   0       NULL        5
AAAA    2           0   0       NULL        5
AAAA    3           2   1       NULL        6
AAAA    4           6   3       8           8
AAAA    5           1   0       NULL        9
AAAA    6           0   1       7           7
AAAA    7           0   3       NULL        4
Run Code Online (Sandbox Code Playgroud)

我可以使用游标执行此操作,但有没有办法使用查询?

Gio*_*sos 10

您可以使用以下查询:

select ROUTE, StopNumber, ONS, OFFS, SPOT_CHECK,
       COALESCE(SPOT_CHECK, ONS - OFFS) AS ld,
       SUM(CASE WHEN SPOT_CHECK IS NULL THEN 0 ELSE 1 END) 
       OVER (PARTITION BY ROUTE ORDER BY StopNumber) AS grp
from BusLoad
Run Code Online (Sandbox Code Playgroud)

要得到:

ROUTE   StopNumber  ONS OFFS    SPOT_CHECK  ld  grp
----------------------------------------------------
AAAA    1           5   0       NULL        5   0
AAAA    2           0   0       NULL        0   0
AAAA    3           2   1       NULL        1   0
AAAA    4           6   3       8           8   1
AAAA    5           1   0       NULL        1   1
AAAA    6           0   1       7           7   2
AAAA    7           0   3       NULL       -3   2
Run Code Online (Sandbox Code Playgroud)

所有你现在想要的是运行总计ld超过ROUTE, grp数据的分区:

;WITH CTE AS (
 ....
 previous query here
)
select ROUTE, StopNumber, ONS, OFFS, SPOT_CHECK, grp,
       sum(ld) over (PARTITION BY ROUTE, grp ORDER BY StopNumber) as load
from cte
Run Code Online (Sandbox Code Playgroud)

在这里演示

注意:上述查询适用于从2012年开始的版本.如果您想要查询2008,则必须以某种方式进行模拟sum() over (order by ...).你可以在SO找到很多相关的帖子.