在 SQL 中计算 运行 总数的最快方法
Fastestest way of calculating Running Totals in SQL
我想计算 select 查询的每一行中的总计 运行 ,以便我可以根据该总计过滤得到 returned 的行。在我看来,我只有两个选择。
- 在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
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 中有三行,您可能会发现联接效果更好。这就是大数法则:有时令人惊讶的事情会发生在较小的数字上。
我想计算 select 查询的每一行中的总计 运行 ,以便我可以根据该总计过滤得到 returned 的行。在我看来,我只有两个选择。
- 在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
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 中有三行,您可能会发现联接效果更好。这就是大数法则:有时令人惊讶的事情会发生在较小的数字上。