SQL - How to Calculate Account Balances in Gnucash?

89 Views Asked by At

Title: How to Calculate Account Balances in Gnucash with Recursive SQL

Hello Stack Overflow Community,

I've been using Gnucash for a year and recently attempted to create custom reports for my financial data. However, I encountered a challenge while trying to calculate the cumulative values of accounts, including their sub-accounts.

Database Schema:

I'm working with the following tables in my Gnucash database: (https://piecash.readthedocs.io/en/master/_images/schema.png)

  • 'accounts'
  • Columns: guid, name, account_type, commodity_guid, commodity_scu, non_std_scu, parent_guid, code, description, hidden, placeholder
  • Example data provided:
guid name account_type commodity_guid commodity_scu non_std_scu parent_guid code description hidden placeholder
1fb9d8623ae04501a62b71dd0d5f1f8d Root Account ROOT 0 0 0 0
7c222beb8a7c439399d1ac4850ba09fb Accruals ASSET dbf3687850b3411a8b548d48a6e961ee 100 0 681fe705237c4ba39026ac7ab5b48b58 1.3 0 0
b3f3021120954d1e83c651e6de131e0b Accounts Receivable ASSET dbf3687850b3411a8b548d48a6e961ee 100 0 681fe705237c4ba39026ac7ab5b48b58 1.2 0 0
12ffda3963ab46d4b8f95635c3a1debe Liabilities LIABILITY dbf3687850b3411a8b548d48a6e961ee 100 0 1fb9d8623ae04501a62b71dd0d5f1f8d 2 0 0
3ee7b0171d9b4b76aae67e701ae3ed0e Accounts Payable LIABILITY dbf3687850b3411a8b548d48a6e961ee 100 0 12ffda3963ab46d4b8f95635c3
  • 'transactions'
  • Columns: guid, currency_guid, num, post_date, enter_date, description
  • Example data provided
guid currency_guid num post_date enter_date description
e7a4c802ca2b4f90a167e3376199ad97 dbf3687850b3411a8b548d48a6e961ee ########## ########## Openin Balance - Wallet
387f19734c9042f982f023b754b55fe2 dbf3687850b3411a8b548d48a6e961ee ########## ########## Public Transport
057ce32f70d44ccdbb043aaa3fa6a54f dbf3687850b3411a8b548d48a6e961ee ########## ########## Water
59c8e5fa1a9b45cea20fe1b5453e7743 dbf3687850b3411a8b548d48a6e961ee ########## ########## Income - Gift
2e34c3b14e464144a30690a7b3ab873e dbf3687850b3411a8b548d48a6e961ee ########## ########## Junk Food
  • 'splits'
  • Columns: guid, tx_guid, account_guid, memo, action, reconcile_state, reconcile_date, value_num, value_denom, quantity_num, quantity_denom, lot_guid
  • Example data provided:
guid tx_guid account_guid memo action reconcile_state reconcile_date value_num value_denom quantity_num quantity_denom lot_guid
4c8e31391a994309835ccf22041716b7 e7a4c802ca2b4f90a167e3376199ad97 a35d4345406045189f726a23a4d9f6be n ########## 2000 100 2000 100
96bc3cb0d8a140468d672f8fe6f37ab4 e7a4c802ca2b4f90a167e3376199ad97 1652d2056e9f423c95d187614f60be3e n ########## -2000 100 -2000 100
bdd077bbcc0d44d78059b8ac32f07032 387f19734c9042f982f023b754b55fe2 7e71a62c60a1493b9660a35ed287a968 n ########## 1000 100 1000 100
5088a553afbb478e8367a5d751746200 387f19734c9042f982f023b754b55fe2 a35d4345406045189f726a23a4d9f6be n ########## -1000 100 -1000 100
d4a62d10713e4c45b58e35c52f707a7f 057ce32f70d44ccdbb043aaa3fa6a54f 47131155460843279406277871f98d6e n ########## 500 100 500 100

My Goal:

I aim to generate financial reports that summarize the account balances, including sub-accounts. The desired outcome can be visualized as shown in this image: (https://ibb.co/jyPzpXY)

Challenges:

I attempted to achieve this using the following recursive SQL query:

WITH RECURSIVE AccountHierarchy AS
    (SELECT a.guid,
            a.parent_guid,
            a.code,
            a.name,
            0 AS level,
            SUM(COALESCE(s.value_num, 0)) as value_num
     FROM accounts a
     LEFT JOIN splits s ON a.guid = s.account_guid
     WHERE parent_guid IS NULL
     GROUP BY a.guid,
              a.parent_guid,
              a.code,
              a.name
     UNION ALL SELECT a2.guid,
                      a2.parent_guid,
                      a2.code,
                      a2.name,
                      ah.level + 1 AS level,
                      SUM(COALESCE(s2.value_num, 0)) + SUM(ah.value_num) AS value_num
     FROM accounts AS a2
     JOIN AccountHierarchy AS ah ON a2.parent_guid = ah.guid
     LEFT JOIN splits s2 ON a2.guid = s2.account_guid
     GROUP BY a2.guid,
              a2.parent_guid,
              a2.code,
              a2.name,
              ah.level)
SELECT guid,
       parent_guid,
       level,
       code,
       name
FROM AccountHierarchy
WHERE parent_guid IS NOT NULL
ORDER BY code,
         level,
         name;

However, I encountered an error:

ERROR: aggregate functions are not allowed in a recursive query's recursive term

Question:

How can I modify my SQL query or approach to successfully calculate the account balances, including their sub-accounts, as shown in the desired query image? I would greatly appreciate any guidance or suggestions to help me overcome this challenge.

Thank you in advance!


This revised version of your question provides a clear and concise description of your issue, includes relevant details, and presents the problem you're facing. It also mentions your desired outcome and the specific error you encountered, making it suitable for Stack Overflow.

0

There are 0 best solutions below