【发布时间】:2021-10-23 13:11:27
【问题描述】:
我有一个问题,工作在一周开始时“到期”,并且每周都有一定数量的“空档”可用于完成任何未完成的工作。如果没有足够的空位,则作业将滚动到下周。
我的初始表格如下所示:
| Week | Slots | Due |
|---|---|---|
| 23/8/2021 | 0 | 1 |
| 30/8/2021 | 2 | 3 |
| 6/9/2021 | 5 | 2 |
| 13/9/2021 | 1 | 4 |
我想在每周结束时保持“到期”作业的运行总数。 每周到期的数量将被添加到上周的运行总数中,然后将减去本周的插槽数量。如果有足够的槽位来完成所需的所有作业,则运行总数将为 0(永远不会为负数)。
作为一个例子 - 下面显示了我将如何在 javascript 中实现这一点:
var Total = 0;
data.foreach(function(d){
Total += d.Due;
Total -= d.Slots;
Total = Total > 0 ? Total : 0;
d.Total = Total;
});
结果如下:
| Week | Slots | Due | Total |
|---|---|---|---|
| 23/8/2021 | 0 | 1 | 1 |
| 30/8/2021 | 2 | 3 | 2 |
| 6/9/2021 | 5 | 2 | 0 |
| 13/9/2021 | 1 | 4 | 3 |
我是否可以在 SQL(特别是 SQL Server 2012)中实现这一点
我尝试过各种形式的sum(xxx) over (order by yyy)
我管理的最近的是:
sum(Due) over (order by Week) - sum(Slots) over (order by Week) as Total
这提供了一个运行总数,但当有多余的插槽时将提供一个负数。
这是用光标完成此操作的唯一方法吗?如果是这样 - 有什么建议吗?
谢谢。
【问题讨论】:
-
使用递归查询遍历行。
-
“带”光标?还是“没有”光标?您应该尽可能使用基于集合的操作。
-
您将不得不使用某种递归。 Thorsten 提到了递归查询——很好,我觉得它的语法有点陌生。光标是另一种选择,语法过于复杂。我建议使用
while声明。 -
循环总计算 = 到期 - 插槽。如果值为负数,则它认为由于运行总计算或这背后的任何逻辑。请解释一下。
-
@Rahul Biswas:我认为 JHW 已经很好地解释了这一点。无法满足 2021 年 8 月 23 日到期的 1,因为插槽为 0。因此它添加到 2021 年 8 月 30 日的到期 3。这使得 4,但只有 2 个插槽。因此,在 2021 年 6 月 9 日,剩余的 2 个被添加到日期的 2 个到期日,即 4 个。有 5 个插槽,所以什么都没有。这是一个迭代过程,因为您不能只是将会费和插槽相加。到期 1,无论您有 1 个插槽还是 1000 个插槽都没有区别。您需要一个循环。 SQL 中的循环意味着递归查询。
标签: sql sql-server tsql common-table-expression recursive-query