大家好,感谢您的帮助。
我有以下情况:一个名为 statements 的表,其中包含字段id (int)、stmnt_date (date)、debit (double)、credit (double) 和balance (double)
我想按照以下规则计算余额:
第一行余额(按时间顺序)=借方-贷方,其余行
当前行余额 = 按时间顺序排列的前一行余额 + 当前行借方 - 当前行贷方
正如您在上面的图片中看到的那样,行没有按日期排列,这就是为什么我按时间顺序两次使用这个词来强调 stmnt_date 值的重要性。
非常感谢您的帮助。
假设
stmnt_date
有一个UNIQUE
约束,使用窗口/分析函数会很容易:不幸的是,MySQL(还)没有实现分析功能。您可以使用严格的 SQL,通过自连接表(虽然 100% 工作但效率应该相当低)或通过使用特定的 MySQL 功能、变量(这将非常有效,但您必须对其进行测试)来解决问题升级 mysql 时,确保结果仍然正确,并且不会因某些优化改进而受损):
使用您的数据,它将导致:
我认为您可以尝试以下方法:
ypercube 的答案非常壮观(我从未见过通过这样的虚拟选择在单个查询中创建变量),所以为了您的方便,这里是 CREATE TABLE 语句。
对于 Google Image Search 中的表格数据图像,您可以使用https://convertio.co/ocr/或https://ocr.space/将其转换为文本文档。然后,如果 OCR 没有正确检测列,并且您有 Mac,请使用TextWrangler并按住选项键来执行矩形选择并四处移动列。Sequel Pro、TextWrangler 等SQL 编辑器和Google Docs等电子表格的组合使得处理制表符分隔的表格数据非常有效。
如果我可以将所有这些都放在评论中,我会的,所以请不要赞成这个答案。
自连接表在大表上不是很快。所以在 PostgreSQL 上处理这个任务我决定使用触发函数来计算存储字段“余额”。每行的所有计算只发生一次。
例如,在 MSSQL 中:
使用 with() 语句生成 CTE。这本质上是一个临时结果集,它将显示每一行的值。您可以在 with 语句中使用 math 在末尾创建一列,使用 math 显示该行的总计为 DEBIT-CREDIT。在您的 with 语句中,您需要为每一行分配行号,使用 WITH () 的 OVER 子句按 stmnt_date 排序。
然后,使用 a.ROWNUMBER= b.ROWNUMBER-1 或 +1 递归地将表连接到自身上,这将允许您引用此行和上一行的 a.total+b.total= 总计。
我很感激我没有提供代码,但这是实现这一目标的实用方法。如果需要,我可以提供代码:)