按日期分组的mysql平衡计算

时间:2013-11-17 15:16:53

标签: mysql

那么让我来描述我想在这里计算的内容。我有2个表,在第一个表上称为余额我每个帐户都有一行及其相应的当前余额。在第二个表中我拥有这些帐户的所有存款和取款以及这些存款和取款的确切日期时间发生。我的问题是根据这两个表计算每天所有账户的余额。

1.表余额

|account_id| balance |
|1111      |   1000  |
|2222      |   3500  |
|3333      |   10000 |

2.信用额度

account_id|         date      |deposit_withdrawal|
|1111     |2012-11-11 12:35:02|        250       |
|1111     |2012-11-12 18:15:34|        750       |
|1111     |2012-11-12 09:09:04|       -150       |
|2222     |2012-01-12 10:05:04|       1000       |
|2222     |2012-07-15 14:23:04|        -340      |
|2222     |2012-12-29 13:01:04|        450       |

我从信用表中选择账户,得到存款_提款的总和,然后按DAYOFYEAR分组。现在我被卡住了,我无法弄清楚如何在每个日期计算他们的余额。如上所述,余额表包含帐户的当前余额。因此,deposit_withdrawal表中的最新条目已计入余额表中。

SELECT c.account_id , c.date , SUM(c.deposit_withdrawal)  FROM credit c
JOIN balance b  on b.account_id = c.account_id
GROUP by DAYOFYEAR (c.date)
ORDER BY DAYOFYEAR(c.date) DESC
编辑:谢谢大家的回复,让我再多解释一下,假设我们有一个当前余额为2000的账户。在表中,他有3个参赛作品,1个在2012-10-10,退出在2012-11-11有300,1,存款400,最后一个和最近的一个在2013-02-29,存款150.我想要做的是找到他的所有日期之间的余额2013-02-29和2012-10-09。我知道在2013-02-29这是最近的一次,他的余额等于他目前的余额= 2000.所以前一天,在2013-02-28我知道他的余额将是当前余额(2000) - 最后存款(150)= 1850.直到2012-11-11他的余额没有变化。在2012-11-11他已经存入400,所以前一天在2012-11-10他的余额将是1850-400 = 1450等等。

1 个答案:

答案 0 :(得分:0)

当您添加新记录时,您应该将余额存储在信用表中,这会使事情变得更简单。但是 - 我们可以在没有历史信息的情况下解决这个问题,我们只需要构建某种交易历史。

我们可以通过查看每个信用记录,查找其后的记录并将其应用于余额来实现此目的:

CREATE TABLE transaction_history (
SELECT
    credit.account_id,
    credit.`date`,
    credit.deposit_withdrawal,
    COALESCE(balance.balance - SUM(next_transactions.deposit_withdrawal), balance.balance) AS balance
FROM
    credit
LEFT JOIN
    credit AS next_transactions
ON
    next_transactions.account_id = credit.account_id
AND
    next_transactions.`date` > credit.`date`
INNER JOIN
    balance
ON
    balance.account_id = credit.account_id
GROUP BY
    credit.account_id,
    credit.`date`,
    credit.deposit_withdrawal
ORDER BY
    credit.`date` DESC
);

这会为每个信用记录生成每个帐户的余额。但要正确使用它,我们需要考虑帐户的起始余额:

INSERT INTO transaction_history (account_id, `date`, deposit_withdrawal, balance) (
SELECT
    balance.account_id,
    '0000-00-00 00:00:00',
    0,
    COALESCE(earliest_transaction.balance - earliest_transaction.deposit_withdrawal, balance.balance) AS `balance`
FROM
    balance
LEFT JOIN
    transaction_history AS earliest_transaction
ON
    earliest_transaction.account_id = balance.account_id
AND
    earliest_transaction.`date` = (SELECT MIN(`date`) FROM transaction_history AS te WHERE te.account_id = balance.account_id)
);

这会在应用任何其他交易之前将时间0的记录作为余额插入,因此帐户1111有150,帐户2222有2390,帐户3333有10000.您应该得到如下数据:

mysql> SELECT * FROM transaction_history;
+------------+---------------------+--------------------+---------+
| account_id | date                | deposit_withdrawal | balance |
+------------+---------------------+--------------------+---------+
|       2222 | 2012-12-29 13:01:04 |                450 |    3500 |
|       1111 | 2012-11-12 18:15:34 |                750 |    1000 |
|       1111 | 2012-11-12 09:09:04 |               -150 |     250 |
|       1111 | 2012-11-11 12:35:02 |                250 |     400 |
|       2222 | 2012-07-15 14:23:04 |               -340 |    3050 |
|       2222 | 2012-01-12 10:05:04 |               1000 |    3390 |
|       1111 | 0000-00-00 00:00:00 |                  0 |     150 |
|       2222 | 0000-00-00 00:00:00 |                  0 |    2390 |
|       3333 | 0000-00-00 00:00:00 |                  0 |   10000 |
+------------+---------------------+--------------------+---------+
9 rows in set (0.00 sec)

然后,如果您想在特定日期结束时查找给定帐户的余额,可以使用此查询:

SELECT 
    balance 
FROM 
    transaction_history 
WHERE 
    account_id = 1111 
AND 
    `date` <= '2012-11-12 23:59:59'  
ORDER BY 
    `date` DESC 
LIMIT 1;