从交易中计算余额

时间:2019-11-19 12:02:24

标签: sql tsql

我有一个看起来像这样的表

ID  Type    Amount  Created
10  4   30,00   2019-11-29 11:34:54.417
1   1   10,50   2019-11-19 11:34:54.417
3   2   16,50   2019-11-17 11:34:54.417
2   4   11,50   2019-11-15 11:34:54.417
4   6   10,00   2019-11-11 11:34:54.417
5   3   8,60    2019-10-19 11:34:54.417
7   1   21,50   2019-05-19 11:34:54.417
8   4   9,00    2019-04-19 11:34:54.417
9   1   8,00    2019-02-19 11:34:54.417
6   1   1,50    2019-01-19 11:34:54.417

想象一下,此表保留了一个电子钱包,这些是ID为,类型(取款,冲销,存款等),金额和创建日期的交易。 可以说所有这10笔交易都是针对特定客户的。因此,如果我运行

SELECT SUM(Amount) AS Balance
FROM  transactions
WHERE Created <= '20191120'

此查询将返回该客户的余额,直到2019/11/20。

我想要的是对此表运行选择查询,并仅保留Type = 4的事务。 例如

SELECT  ID
    ,   Type
    ,   Amount
    ,   Created
FROM    transactions
WHERE type=4

此查询返回以下

ID  Type    Amount  Created
2   4   11,50   2019-11-15 11:34:54.417
8   4   9,00    2019-04-19 11:34:54.417
10  4   30,00   2019-11-29 11:34:54.417

我真正想要的是此结果集中的额外一列,该列显示了每笔交易(类型= 4)时客户的余额。例如,当他进行ID = 2的交易时,他之前的余额(不计算当前(id = 2 ))是(1,50 + 8,00 + 9,00 + 21,50 + 8,60 + 10,00),当他进行ID = 8的交易时,其余额为(1,50 + 8,00),依此类推。

所需的结果集应为

  ID    Type    Amount  Created  Balance
2   4   11,50   2019-11-15 11:34:54.417  58,60
8   4   9,00    2019-04-19 11:34:54.417  9,50
10  4   30,00   2019-11-29 11:34:54.417  97,1

我要在一个“选择查询”中执行此操作。我有分两步进行操作的想法,但这不是我的意图,我只需要运行一次并拥有所有五个所需的列即可。

2 个答案:

答案 0 :(得分:1)

假设您的DBMS支持窗口功能,请仔细查看所需的输出,您可以使用伪累积和来实现:

import * as React from "react";

export class FileSelector extends React.Component<undefined, undefined>
{
    constructor(props: any)
    {
        super(props);
        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(selectorFiles: FileList)
    {
        console.log(selectorFiles);
    }

    render ()
    {
        return <div>
            <input type="file" onChange={ (e) => this.handleChange(e.target.files) } />
        </div>;
    }
}

SQL Fiddle

此外,SELECT ID, Type, Amount, Created, Balance FROM ( SELECT ID, Type, Amount, Created, SUM(Amount) OVER(-- Sum "amount" of all rows before current row (exclude current row) ORDER BY Created ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) AS Balance FROM transactions ) src WHERE type = 4 ORDER BY id ; 的余额不应该是id=258,6的余额应该不应该是id=10吗?

答案 1 :(得分:0)

您需要累计和并进行过滤:

SELECT t.*
FROM (SELECT t.*, SUM(Amount) OVER (ORDER BY Created) - Amount AS Balance
      FROM  transactions t
      WHERE Created <= '20191120'
     ) t
WHERE type = 4;