在 SQL 中计算 运行 总数的最快方法

Fastestest way of calculating Running Totals in SQL

我想计算 select 查询的每一行中的总计 运行 ,以便我可以根据该总计过滤得到 returned 的行。在我看来,我只有两个选择。

  1. 在select语句中使用over并将主查询设为子查询

示例:

SELECT DocDate,
       Debit,
       RunningTotal
FROM
(
    SELECT T1.DocDate,
           T1.Debit,
           SUM(T1.Debit) OVER(ORDER BY T1.DocDate DESC) AS RunningTotal
        FROM Invoices T1
) AS T
WHERE RunningTotal < @CurrentBalance 
  1. Join table 自身

示例:

SELECT T1.DocDate,
       T1.Debit,
       SUM(T2.Debit) AS RunningTotal
FROM Invoices T1
JOIN Invoices T2 ON T1.DocDate <= T2.DocDate
GROUP BY T1.DocDate,
   T1.Debit
   HAVING SUM(T2.Debit) < @CurrentBalance
ORDER BY T1.DocDate DESC

两个查询 return 完全相同的结果。尽管在性能方面,建议的方法是什么?

除非你的 table 行数太少以至于你可以一只手数出来,否则内置的 window 函数会更快。

为什么?首先,它是内置的,专为此目的而设计。

其次,它实际上计算了一个累计和。因此,在计算第 10 个值时,它是使用第 9 个累加和的结果,并在其上再加一个值。

join 方法是一种特别令人震惊的计算方法。如果您在 table 中有 100 行,那么它将 table 扩展到 100 * 99 / 2 行(给予或接受)——然后必须聚合超过 100 行。您可以看到,随着 table 变大,情况变得更糟。

也就是说,如果 table 中有三行,您可能会发现联接效果更好。这就是大数法则:有时令人惊讶的事情会发生在较小的数字上。