The result you want can be achieved in Firebird 2.5 with use of unions and some additional logic to be able to insert the subtotals and total in the right place. Using a simplified table LEDGER
with the data as you have shown, you can use the following query:
SELECT
CASE LTYPE
WHEN 0 THEN CAST(ledger_account AS VARCHAR(50))
WHEN 1 THEN 'Subtotal'
WHEN 2 THEN 'TOTAL'
END AS LEDGER_ACCOUNT_DISPLAY,
AMOUNT
FROM (
SELECT ledger_account, amount, 0 AS LTYPE
FROM ledger
UNION ALL
SELECT ledger_account, SUM(amount), 1 AS LTYPE
FROM ledger
GROUP BY ledger_account
UNION ALL
-- BIN_SHL(1, 31) - 1 produces the maximum value of INTEGER; for sorting total at end
SELECT BIN_SHL(1, 31) - 1, SUM(amount), 2 AS LTYPE
FROM ledger
) a
ORDER BY ledger_account, LTYPE
With Firebird 3 you can also try a different approach using window functions. This solution will not produce additional rows for subtotals and total, but produce them inline. It could then be the responsibility of your presentation layer to show them correctly:
SELECT ledger_account,
amount,
SUM(amount) OVER(PARTITION BY ledger_account) AS subtotal,
SUM(amount) OVER() AS total
FROM ledger
ORDER BY ledger_account