计算每日最低余额
假设我有一个名为 transaction 的表,其中包含 transaction_date、存款、取款字段。一天可能有也可能没有交易,但每天可以有多个交易。所以,我需要做的是给定一个日期范围,比如2010年12月1日到2010年12月31日,我需要计算出每天的最低余额。我们假设 2010 年 12 月 1 日之前也有交易。有人可以给我一个关于这个的想法吗?
谢谢。
更新 示例
tran_date withdraw deposit
2010-11-23 0.00 50.00
2010-12-10 0.00 50.00
2010-12-10 0.00 200.00
2010-12-12 100.00 0.00
2010-12-20 0.00 50.00
2010-12-20 70.00 0.00
2010-12-20 0.00 50.00
2010-12-20 0.00 50.00
2010-12-24 150.00 0.00
在上面的示例中,从12 月 1 日到12 月 10 日的最低每日余额为 50。 12 月 10 日有两笔存款总计 70,但当天的最低余额为 50(从前一天结转)。
现在让我们看看多笔交易。
12 月 20 日结转为 200。第一笔存款为250,第二笔存款为180,第三笔存款为230,最后一笔交易为 280。因此,在当天的第二笔交易中提取 70 后,当天的最低余额将为 180。是否可以使用 PostgreSQL 8.4 上的查询生成此内容,还是应该使用其他方法?
Let's say I have a table named transaction with transaction_date, deposit, withdrawal fields. There may or may not be transaction on a day but can have multiple transactions for each day. So, what I need to do is given a date range, say December 1, 2010 to December 31, 2010, I need to figure out the minimum balance on each day. Let's assume there are transactions before December 1, 2010 as well. Is there anyone who can give me an idea on this one?
Thank you.
Update With Example
tran_date withdraw deposit
2010-11-23 0.00 50.00
2010-12-10 0.00 50.00
2010-12-10 0.00 200.00
2010-12-12 100.00 0.00
2010-12-20 0.00 50.00
2010-12-20 70.00 0.00
2010-12-20 0.00 50.00
2010-12-20 0.00 50.00
2010-12-24 150.00 0.00
In above example, the minimum daily balance from Dec 1 to Dec 10 would be 50. On Dec 10 there are two deposits totaling 70 but the minimum balance on that day would be 50 (carried over from previous day).
Now lets look at multiple transactions.
The carried over on Dec 20 is 200. The first deposit makes it 250, the second one makes it 180, the third one makes it 230 and the last transaction makes it 280. So, the minimum balance for that day would be 180 after withdrawing 70 on the second transaction of the day. Is it possible to generate this using a query on PostgreSQL 8.4 or should I use another approach?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
编辑2
这是一个完整的示例,包括前一天的(最小)余额(据我所知,用这么小的一组数据)。它应该在 8.4 上运行。
我重构了派生表以使用 CTE(通用表表达式)以使其(希望)更具可读性:
Edit2
This is a full example, including the (minimum) balance from the previous day (as far as I can tell with such a small set of data). It should run on 8.4.
I refactored the derived tables to use CTE (common table expression) to make it (hopefully) a bit more readable:
忽略其他答案中的所有内容。马伏里奥那个家伙是个吹牛者和白痴。试试这个:
当我想到这个时,我正要入睡。 IFNULL 可能是 MySQL 特有的东西,但你可以找到 Postgres 的等效项。
Ignore everything in that other answer. That guy Malvolio is an blowhard and an idiot. Try this instead:
I was just about to fall asleep when this occurred to me. The IFNULL may be a MySQL specific thing, but you can find a Postgres equivalent.
我假设您所说的最低余额是一天开始时或一天结束时的余额较少?
我想你每天都会做这样的事情:
前一天的余额:(
不确定如何在 PostgreSQL 中进行日期比较
然后:
然后以较大者为准。
如果这不是你的意思,我们需要更多信息。
I'm assuming by minimum balance that you're talking about which you have less at, the start or the end of the day?
I suppose for each day you'd do something like this:
Balance from day before:
(not sure how date comparison would be done in PostgreSQL
Then:
Then whichever is greater.
If that's not what you meant, we need more info.
首先,我假设交易是按顺序编号的。根据定义,交易必须正确排序(因为在同一天存款 50 美元,然后取款 50 美元,按照不同的顺序执行相同的步骤会产生截然不同的结果),并且按顺序对它们进行编号可以使其他事情变得更加容易。然后我们必须做一些程序上的挥手:(
请原谅任何拼写错误——我手头没有 PostGres)。现在我们有了一个包含所有余额的表,我们只需将其挖出来即可。
我无法在这里测试它,但它应该可以工作。
First, I'm going to assume that the transactions are sequentially numbered. Just by definition, the transactions have to be properly ordered (because a $50 deposit followed by a $50 withdrawal on the same day would produce a very different answer from the same steps in a different order) and numbering them sequentially makes other things much easier. Then we have to do some procedural handwaving:
(Forgive any typos -- I don't have PostGres handy). Now we have a table with all the balances in it, we just have to dig it out.
I can't test this here, but it should work.
假设您对一天内的交易进行编号,我采用以下模式:
然后,以下查询将为您提供答案:
但请注意,您需要 PostgreSQL 9.0,因为
1 PRECEDING
子句早期版本不支持。如果您无法升级,您可能需要某种程序解决方案,就像其他答案所建议的那样。无论如何,我建议为此编写单元测试。 ;-)
Assuming you number your transactions within a day, I took the following schema:
Then, the following query appears to give you your answer:
Note, however, that you need PostgreSQL 9.0 for that because the
1 PRECEDING
clause is not supported in earlier versions. If you can't upgrade, you will probably need some kind of procedural solution like the other answers suggest.In any case I recommend writing unit tests for this. ;-)
为什么不在数据库中添加一列来跟踪当前余额(在每次存款/取款时计算)。这样,只需返回您感兴趣的日期范围内该列的最小值即可。
Why don't you add a column to the database that tracks the current balance (calculated at each deposit/withdrawal). That way it would simply a case of returning the minimum for that column within the date range you're interested in.
谢谢大家的帮助。我使用以下方法来解决这个问题。我不知道代码的效率如何。
再次感谢您的所有帮助。
Thank you everyone for the help. I've used the following to solve this. I don't know how efficient the code is though.
Again, thanks for all your help.