使用基于集合的操作快速计算sql server中的运行总计

使用基于集合的操作快速计算sql server中的运行总计,sql,sql-server,sql-server-2008,Sql,Sql Server,Sql Server 2008,我有一些数据如下所示: +---+--------+-------------+---------------+--------------+ | | A | B | C | D | +---+--------+-------------+---------------+--------------+ | 1 | row_id | disposal_id | excess_weight | total_weight

我有一些数据如下所示:

+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 30           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 50           |
| 7 | 6      | 2           | 15            | 50           |
| 8 | 7      | 2           | 5             | 50           |
| 9 | 8      | 2           | 5             | 50           |
+---+--------+-------------+---------------+--------------+
+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 20           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 45           |
| 7 | 6      | 2           | 15            | 45           |
| 8 | 7      | 2           | 5             | 30           |
| 9 | 8      | 2           | 5             | 25           |
+---+--------+-------------+---------------+--------------+
我把它变成这样:

+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 30           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 50           |
| 7 | 6      | 2           | 15            | 50           |
| 8 | 7      | 2           | 5             | 50           |
| 9 | 8      | 2           | 5             | 50           |
+---+--------+-------------+---------------+--------------+
+---+--------+-------------+---------------+--------------+
|   |   A    |      B      |       C       |      D       |
+---+--------+-------------+---------------+--------------+
| 1 | row_id | disposal_id | excess_weight | total_weight |
| 2 | 1      | 1           | 0             | 30           |
| 3 | 2      | 1           | 10            | 30           |
| 4 | 3      | 1           | 0             | 20           |
| 5 | 4      | 2           | 5             | 50           |
| 6 | 5      | 2           | 0             | 45           |
| 7 | 6      | 2           | 15            | 45           |
| 8 | 7      | 2           | 5             | 30           |
| 9 | 8      | 2           | 5             | 25           |
+---+--------+-------------+---------------+--------------+
基本上,我需要更新total_weight列,方法是从表中属于同一处置id的前几行中减去多余的_权重之和


我目前正在使用光标,因为它比我尝试过的其他解决方案(cte、三角形连接、交叉应用)更快。我的cursor解决方案保留一个运行总数,对于每个新的Disposition_id,该总数将重置为零,增加多余的重量,并在需要时执行更新,运行时间约为40秒。我尝试过的其他解决方案耗时3-5分钟,我想知道是否有一种相对高效的方法可以使用基于集合的操作来实现这一点?

您可能已经尝试过的另一种解决方案是执行与找到的答案类似的操作


除非您使用的是Oracle,它的累计总和相当不错,否则最好使用游标。充其量,您将不得不将表重新连接到它本身,或者使用其他方法来执行应该是O(n)操作的操作。一般来说,针对此类问题的基于集合的解决方案比较混乱或非常混乱

“前几行”表示排序。所以没有-没有基于集合的操作


Oracle的领先和落后就是为此而建立的,但SQL Server迫使您加入三角联接。。。我想您已经对此进行了调查。

我花了很多时间优化此类查询,最终得到了两个性能选项:存储预先计算的运行总数,如中所述,或者在客户端上计算它们,这也很快且简单。

我最近在博客中谈到了这一点: