首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 累計值查詢:銀行帳戶餘額計算實戰

     編輯:關於SqlServer

在財務、庫存、物流等場景中,依時間序列計算「執行中總計」是核心需求。本文以銀行帳戶交易為例,示範如何在 SQL Server 中高效實現累計餘額查詢,並探討效能優化策略。

場景建模

假設交易表 Transactions 結構如下:

TxnID   INT PRIMARY KEY
TxnDate DATETIME DEFAULT GETDATE()
Amount  MONEY       -- 正數=存入,負數=提領

範例資料:

TxnIDTxnDateAmount
12006-11-03 02:33:42.34010000.00
22006-11-03 02:34:50.467-500.00
32006-11-03 02:35:04.857250.00
42006-11-03 02:42:19.763-124.25

核心查詢:自我連接法

利用自我連接,將每筆交易與「時間早於或等於該筆」的所有交易聚合:

SELECT 
    T1.TxnID,
    T1.TxnDate,
    T1.Amount,
    SUM(T2.Amount) AS RunningBalance
FROM Transactions T1
JOIN Transactions T2 
    ON T2.TxnDate <= T1.TxnDate
   AND (T2.TxnDate < T1.TxnDate OR T2.TxnID <= T1.TxnID)  -- 同秒排序保護
GROUP BY T1.TxnID, T1.TxnDate, T1.Amount
ORDER BY T1.TxnDate, T1.TxnID;

結果:

TxnIDTxnDateAmountRunningBalance
12006-11-03 02:33:42.34010000.0010000.00
22006-11-03 02:34:50.467-500.009500.00
32006-11-03 02:35:04.857250.009750.00
42006-11-03 02:42:19.763-124.259625.75

進階:多帳戶支援

新增 AccountID 欄位,查詢改為:

SELECT 
    T1.AccountID, T1.TxnID, T1.TxnDate, T1.Amount,
    SUM(T2.Amount) AS RunningBalance
FROM Transactions T1
JOIN Transactions T2 
    ON T2.AccountID = T1.AccountID
   AND T2.TxnDate <= T1.TxnDate
   AND (T2.TxnDate < T1.TxnDate OR T2.TxnID <= T1.TxnID)
WHERE T1.AccountID = @TargetAccount  -- 可選參數
GROUP BY T1.AccountID, T1.TxnID, T1.TxnDate, T1.Amount
ORDER BY T1.AccountID, T1.TxnDate, T1.TxnID;

效能優化關鍵

  • 索引策略: 建立 CREATE INDEX IX_Transactions_Acc_Date_ID ON Transactions(AccountID, TxnDate, TxnID) INCLUDE (Amount),實現索引覆蓋與順序掃描。
  • 視窗函數替代方案: SQL Server 2012+ 可用 SUM(Amount) OVER (PARTITION BY AccountID ORDER BY TxnDate, TxnID ROWS UNBOUNDED PRECEDING),執行計畫更優、碼更簡潔。
  • 避免游標/迴圈: 集合運算比 RBAR(逐列處理)快數個數量級。

應用延伸

同樣邏輯適用於:

  • 庫存系統:期初量 + 進貨 - 出貨 = 即時可用量
  • 積分系統:歷史獲得 - 歷史兌換 = 當前可用積分
  • 專案營收累計:按里程碑日期累計認列營收

掌握累計值查詢,不僅能滿足報表需求,更能在異常交易排查、審計追蹤中快速定位問題節點。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved