MS Access日期内带排序的累计求和问题排查与优化咨询
MS Access 容器收支累计余额计算问题解决
问题原因
你当前的查询存在循环引用问题:DSum函数引用的是查询自身qryInventoryTransactionsOrder,但查询在执行过程中还未完全生成所有记录的Expr1值,导致后续记录的DSum条件无法正确匹配,从而出现空值。前3条和最后一条的正确结果只是数据加载顺序的巧合,并非稳定逻辑。
修正方案(拆分查询避免循环)
步骤1:创建基础排序查询
先建立一个仅生成排序时间戳的基础查询(命名为qryBaseTransactions),避免在累计计算时依赖未完成的查询结果:
SELECT ContainerId, Quantity, DateTransaction, OrderInDate, DateAdd("s", OrderInDate, DateTransaction) AS TransactionTimestamp FROM InventoryTransactions ORDER BY ContainerId, TransactionTimestamp;
步骤2:基于基础查询计算累计余额
再创建新查询,引用上述基础查询来计算累计余额:
SELECT ContainerId, Quantity, DateTransaction, OrderInDate, TransactionTimestamp, DSum("Quantity", "qryBaseTransactions", "[ContainerId] = " & [ContainerId] & " AND [TransactionTimestamp] <= #" & [TransactionTimestamp] & "#") AS Balance FROM qryBaseTransactions ORDER BY ContainerId, TransactionTimestamp;
注意:如果
ContainerId是文本类型,需要在条件中添加单引号,修改为:"[ContainerId] = '" & [ContainerId] & "' AND [TransactionTimestamp] <= #" & [TransactionTimestamp] & "#"
更优实现方案(子查询替代DSum)
DSum属于域聚合函数,数据量较大时性能较差,推荐使用子查询直接计算累计,逻辑更清晰且性能更稳定:
SELECT t1.ContainerId, t1.Quantity, t1.DateTransaction, t1.OrderInDate, DateAdd("s", t1.OrderInDate, t1.DateTransaction) AS TransactionTimestamp, ( SELECT Sum(t2.Quantity) FROM InventoryTransactions t2 WHERE t2.ContainerId = t1.ContainerId AND DateAdd("s", t2.OrderInDate, t2.DateTransaction) <= DateAdd("s", t1.OrderInDate, t1.DateTransaction) ) AS Balance FROM InventoryTransactions t1 ORDER BY t1.ContainerId, TransactionTimestamp;
这个子查询通过关联同表的t2记录,直接对当前记录之前(含当前)的所有同容器交易求和,避免了循环引用和域函数的性能问题。
内容的提问来源于stack exchange,提问作者st_user_321122
相关产品推荐
相关产品推荐

