我遇到了下面的SQL UPDATE语句,它计算表中的总列数:
UPDATE N1 SET
RunningTotal = (SELECT SUM (SubTotal)
FROM #Sales X1
WHERE
N1.FiscalYear = X1.FiscalYear AND
X1.OrderNumber <= N1.OrderNumber)
FROM
#Sales N1
我以前没有见过这种类型的模式,并且由于搜索SQL语句的困难,我一直无法找到解释。具体来说,我想知道上面的语句是如何更新整个表的;循环是如何发生的?
注意:该语句运行良好;SSMS中显示的前后结果如下所示:
(我在Windows10 x64上使用SQL Server2017社区版。)
发布于 2018-06-09 01:43:20
它并不是真正的循环,但我会解释:
UPDATE N1 SET
RunningTotal = ...
FROM #Sales N1
正因为如此,它正在更新整个表。update上没有where子句,因此无论发生什么情况,每一行都将被更新。我个人更喜欢这种为表设置别名并对别名使用UPDATE的风格,因为当您有复杂的更新时,它可以使查看更改变得更容易。
内部部分:
SELECT SUM (SubTotal)
FROM #Sales X1
WHERE N1.FiscalYear = X1.FiscalYear AND
X1.OrderNumber <= N1.OrderNumber
获取正在处理的订单之前每年的销售金额之和。它不是在代码中循环;它实际上是针对每行或返回的数据运行子查询。
发布于 2018-06-09 01:52:17
您的问题的最佳解决方案是可更新的CTE:
WITH toupdate AS
(SELECT S.*,
SUM(SubTotal) OVER (PARTITION BY FiscalYear ORDER BY OrderNumber) AS new_RunningTotal
FROM #Sales S
)
UPDATE toupdate
SET RunningTotal = new_RunningTotal;
这没有联接或相关子查询。一般而言,窗口函数将比相关子查询等效项快得多。可更新的CTE是SQL Server的一个非常好的特性,它可以让您省去额外的JOIN
。
https://stackoverflow.com/questions/50765720
复制相似问题