Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 计算负载并避免使用游标_Sql_Sql Server - Fatal编程技术网

Sql 计算负载并避免使用游标

Sql 计算负载并避免使用游标,sql,sql-server,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,

给出下表结构,表示乘客使用车门传感器上下车的公交线路。还有一个人坐在那辆公共汽车上,手里拿着一个记分板

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)
我想在此表中添加一列“LOAD”,用于计算每个站点的负载

负载=先前停止负载+当前停止开启-当前停止关闭,如果 抽查为空,否则加载=抽查

预期成果:

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

我可以用光标来实现这一点,但是有没有办法用查询来实现呢?

您可以使用递归查询

with act_load as
(
  select *, ons load
  from busload
  where stopnumber = 1 and route = 'AAAA'
  union all
  select b.*, case when b.spot_check is null then l.load + b.ons - b.offs
              else b.spot_check
              end load
  from busload b
  join act_load l on b.StopNumber = l.StopNumber + 1 and
                     b.route = l.route
)
select *
from act_load

您可以使用以下查询:

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
要获得:

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
您现在所需要的是
ld
over
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


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

您还可以发布预期的结果集吗?您使用的是什么版本的SQL Server?2008或更高版本fine@GiorgosBetsos我包括了预期的结果。感谢您的请求。“或者以后再使用”这是否意味着您可以使用SQL2016功能?真是太好了!您在这里的逻辑帮助我开发了一个相同的解决方案。令人惊叹的!呸!我刚刚得到了与此完全相同的解决方案,但它花费了我9分钟的时间。