Hi Vasily,

thank you so much, I see now how it works!

So, for this ledger

ledger = """
2020-01-01 open Assets:Bank1
2020-01-01 open Assets:Bank2
2020-01-01 open Income:Salary

2020-01-01 * "Salary 1"
  Income:Salary
  Assets:Bank1 10 EUR

2020-01-02 * "Salary 2"
  Income:Salary
  Assets:Bank2 100 EUR

2021-01-20 * "Salary 3"
  Income:Salary
  Assets:Bank2 1000 EUR
"""

and this query
query =f"""
SELECT  account, LAST(balance) AS amount
WHERE date <= 2020-12-31 AND account ~ 'Assets|Liabilities'

"""
I get the following:
account   amount (EUR)
 Assets:Bank1          10.0
 Assets:Bank2         110.0

And for this query
query =f"""
SELECT  LAST(balance) AS amount
WHERE date <= 2020-12-31 AND account ~ 'Assets|Liabilities'

"""
I get the following:

amount (EUR)
        110.0

So, as you said, it does respect the WHERE restriction, but calculated 
balance as a combination of postings to all accounts, which fall into the 
WHERE clause

I think for now I will avoid using *balance *in queries, as it may be 
confusing.

For reporting periodic balances I used to use just a series of queries like 
this, which I would call against every day I want to know balance for

    query = f"""
    SELECT account, convert(SUM(position),'{currency}',{date_iso}) as amount
    where date <= {date_iso} AND account ~ 'Assets|Liabilities'
    """

But as this very inefficient, since there is a lot of re-calculation going 
on, I then developed the class BeanSummator 
<https://github.com/Ev2geny/evbeantools/blob/97f637d9a599d077239f8a9556776a3c82817b4c/src/evbeantools/summator.py#L248>
 with 
the function sum_till_date 
<https://github.com/Ev2geny/evbeantools/blob/97f637d9a599d077239f8a9556776a3c82817b4c/src/evbeantools/summator.py#L292C9-L292C22>which
 
I can call periodically with ascending dates and it would calculate a 
balance for me quite fast, as it stores a pervious calculation.


On Wednesday, March 26, 2025 at 1:08:25 PM UTC+1 Vasily M wrote:

Hi Chary,

I'll start with a disclaimer that I don't have a perfect understanding of 
the "balance" operation intuition. It is useful but it seems it indeed has 
limitations and in particular it doesn't work as expected with GROUP BY 
statements. I think I have seen this mentioned explicitly but couldn't find 
now, at least in the official docs here: 
https://beancount.github.io/docs/beancount_query_language.html, only a 
hint "Access to the previous row is not a standard SQL feature" suggests 
that it might not work as expected.

In your example the issue is not that it doesn't respect the WHERE filter 
(I think it does) but that it aggregates balance between different 
accounts. That will become more obvious if you change 1000 EUR to different 
amounts (say, 500, 600 and 700) in your example transactions.
The partial solution to this is to explicitly use account ~ 'Assets:Bank2' 
in filter. This allows to get total balances for the particular account or 
the group of accounts that you specify in the filter. For example, in this 
case just removing "account" from SELECT will make the query calculate 
correctly the net worth across all Assets+Liabilities.

However, I'll also add that at very least the output of the query (when it 
includes "SELECT account") seems counter-intuitive to me, if not incorrect. 
Not sure if there is at least a way to display a warning if some groupping 
is about to happen that is not related to date groupping (I'm not sure 
about balances inner workings but it seems it's optimised for that). 

P.S. If you choose to try a query for reporting periodic balances, like the 
one I've sent in the neighbouring thread or the one from the 
fava-dashboards repo example, you'll also likely to come across another 
unrelated issue: 
https://github.com/andreasgerstmayr/fava-dashboards/issues/28#issuecomment-2573181426
 
that the rows will not be generated unless there's at least one transaction 
present in the time period. Leaving it here just in case.

Best,
Vasily

On Tuesday, March 25, 2025 at 12:17:19 PM UTC+1 Chary Ev2geny wrote:

Dear all,

I must I still struggle to find a way to use balance to calculate the net 
worth on  certain date (e,g, 2020-12-31 for my example from this thread)

It looks like the *balance *field does not respect the WHERE filter.

In this case, what is the purpose of the balance field all together?


On Sunday, June 2, 2024 at 2:29:23 PM UTC+2 Chary Ev2geny wrote:

Dan,

is it possible to get the result as in the 1st query, but using the *balance 
*?

account amount (EUR)
Assets:Bank1 1000.0
Assets:Bank2 1000.0

On Sunday, June 2, 2024 at 12:36:23 AM UTC+2 [email protected] wrote:

On 01/06/24 21:27, Chary Chary wrote: 
> I am still trying to find the way to calculate the net worth at a 
> certain date using *balance *field (I am not sure it will give me any 
> advantage) 
> 
> But somehow it does not quire work as I expect 
> 
> E.g. 
> 
> ledger_text = """ 
> 
> 2020-01-01 open Assets:Bank1 
> 2020-01-01 open Assets:Bank2 
> 2020-01-01 open Income:Salary 
> 
> 2020-01-01 * "Salary 1" 
>   Income:Salary 
>   Assets:Bank1 1000 EUR 
> 
> 2020-01-20 * "Salary 2" 
>   Income:Salary 
>   Assets:Bank2 1000 EUR 
> 
> 2021-01-20 * "Salary 3" 
>   Income:Salary 
>   Assets:Bank2 1000 EUR 
> """ 
> 
> date_iso = datetime.date(2020,12,31).isoformat() 
> 
> query=f""" 
> select account, SUM(position) as amount 
> where date <= {date_iso}AND account ~ 'Assets|Liabilities' 
> """ 
> 
> result: 
> 
> account amount (EUR) 
> Assets:Bank1 1000.0 
> Assets:Bank2 1000.0 
> 
> 
> This is correct!! 
> Now using balance field 
> query=f""" 
> select account, LAST(balance) as amount 
> where date <= {date_iso}AND account ~ 'Assets|Liabilities' 
> """ 
> account amount (EUR) 
> Assets:Bank1 1000.0 
> Assets:Bank2 2000.0 <==== This is incorrect! 
> So, what am I doing wrong? 

AFAICT, both queries do what they are expected to do. 

Cheers, 
Dan 

-- 
You received this message because you are subscribed to the Google Groups 
"Beancount" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/beancount/b18ada74-706f-4c54-8c0f-338a0c716a2en%40googlegroups.com.

Reply via email to