跳至內容
Astera Technology

同一分鐘的零用金收支,為甚麼顯示同一餘額?

明確訂事件先後,按每一行逐步計餘額,不把同時事件先合在一起。

下載完整個案資料及參考答案 ↓

先準備用來排查的資料

帳目要看每次操作後的餘額。SQLite 的預設有序合計會把相同排序值當同組,所以只按時間,兩筆 09:00 事件都看到合併後餘額。加入次序編號,再明示按行合計。

以下完整建表及資料只在新的 SQLite 測試資料庫執行。全部紀錄均為假設,數量以件計,輸入的 cents 金額欄以貨幣的分存整數;計算後的平均數可能不足整分。小型例子的各表均完整列在預覽。

假設輸入:cash_events
編號事件時間款項變動(分)
12026-10-10 09:0010000
22026-10-10 09:00-3000
32026-10-10 10:00-2000
下載可編輯 CSV ↓
可直接執行的完整測試資料
CREATE TABLE cash_events(id INTEGER PRIMARY KEY,event_at TEXT,delta_cents INTEGER);
INSERT INTO cash_events VALUES (1,'2026-10-10 09:00',10000),(2,'2026-10-10 09:00',-3000),(3,'2026-10-10 10:00',-2000);

重現錯誤結果,再核對更正

錯誤示範查詢:只用來重現問題
SELECT id,SUM(delta_cents) OVER(ORDER BY event_at) AS balance_cents FROM cash_events ORDER BY id;
實際執行的錯誤示範結果
編號餘額(分)
17000
27000
35000
下載可編輯 CSV ↓
更正後的 SQLite 查詢
SELECT id,SUM(delta_cents) OVER(ORDER BY event_at,id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS balance_cents
FROM cash_events ORDER BY id;
更正查詢的實際結果
編號餘額(分)
110000
27000
35000
下載可編輯 CSV ↓

第 1 筆收到後有 10000 分,第 2 筆支出後是 7000,第 3 筆後是 5000。錯誤查詢頭兩筆都顯示 7000,遮蓋收款後曾有的餘額。兩個查詢都不會移動款項。

套用前先測邊界及資料範圍

在同一 10:00 加入較後編號收款,第 3 筆仍是 5000,第 4 筆是 6000;同時事件亦有明確先後。

邊界測試要另開新的假設資料庫,重做完整建表及資料,只套用以下改動,再執行更正查詢。測試改動不可用於正式系統。

新假設副本內的邊界改動
INSERT INTO cash_events VALUES (4,'2026-10-10 10:00',1000);
改動後再執行更正查詢的實際結果
編號餘額(分)
110000
27000
35000
46000
下載可編輯 CSV ↓

編號順序是本例政策。正式帳目須有已確認入帳先後及期初餘額,隨意編號未能證明時間次序。

以上錯誤、更正及邊界結果都已在 SQLite 執行,並與另行編寫的預期資料逐行核對。證據只適用於這組假設條件,未測其他資料庫、正式效能或你的現有資料結構。

相關資源