Beancount Query Language - SQL-achtige Financiële Query's
Beancount beschikt over een krachtige, SQL-achtige Query Language (BQL) waarmee je je financiële data met precisie kunt analyseren. Of je nu een snel rapport wilt genereren, een entry wilt debuggen of een complexe analyse wilt uitvoeren, het beheersen van BQL is essentieel om het volledige potentieel van je plaintext accounting ledger te benutten. Deze handleiding leidt je door de structuur, functies en best practices. 🔍
Query Structuur en Uitvoering
De kern van BQL is de bekende, SQL-geïnspireerde syntax. Query's worden uitgevoerd met behulp van de bean-query command-line tool, die je ledger file verwerkt en de resultaten direct in je terminal teruggeeft.
Basis Query Format
Een BQL query is samengesteld uit drie hoofdclausules: SELECT, FROM en WHERE.
SELECT <target1>, <target2>, ...
FROM <entry-filter-expression>
WHERE <posting-filter-expression>;
SELECT: Specificeert welke kolommen met data je wilt ophalen.FROM: Filtert volledige transacties voordat ze worden verwerkt.WHERE: Filtert de individuele posting lines nadat de transactie is geselecteerd.
Twee-Level Filter Systeem
Het begrijpen van het verschil tussen de FROM en WHERE clausules is cruciaal voor het schrijven van accurate query's. BQL gebruikt een twee-level filterproces.
-
Transactie Level (
FROM) Deze clausule werkt op volledige transacties. Als een transactie aan deFROMconditie voldoet, wordt de volledige transactie (inclusief alle postings) doorgegeven aan de volgende stap. Dit is de primaire manier om data te filteren, omdat het de integriteit van het double-entry accounting systeem bewaart. Bijvoorbeeld, filterenFROM year = 2024selecteert alle transacties die in 2024 hebben plaatsgevonden. -
Posting Level (
WHERE) Deze clausule filtert de individuele postings binnen de transacties die door deFROMclausule zijn geselecteerd. Dit is handig voor presentatie en om te focussen op specifieke legs van een transactie. Wees je er echter van bewust dat filteren op dit level de integriteit van een transactie in de output kan "breken", omdat je mogelijk slechts één kant van een entry ziet. Bijvoorbeeld, je zou alle postings naar jeExpenses:Groceriesaccount kunnen selecteren.
Data Model
Om je data effectief te bevragen, moet je begrijpen hoe Beancount het structureert. Een ledger is een lijst met directives, maar BQL focust primair op Transaction entries.
Transactie Structuur
Elke Transaction is een container met top-level attributen en een lijst met Posting objecten.
Transaction
├── date
├── flag
├── payee
├── narration
├── tags
├── links
└── Postings[]
├── account
├── units
├── cost
├── price
└── metadata
Beschikbare Kolom Types
Je kunt elke attribute van de transactie of zijn postings SELECT-eren.
-
Transactie Attributen Deze kolommen zijn hetzelfde voor elke posting binnen een enkele transactie.
SELECT
date, -- De datum van de transactie (datetime.date)
year, -- Het jaar van de transactie (int)
month, -- De maand van de transactie (int)
day, -- De dag van de transactie (int)
flag, -- De transactie flag, bijv., "*" of "!" (str)
payee, -- De payee (str)
narration, -- De description of memo (str)
tags, -- Een set van tags, bijv., #trip-2024 (set[str])
links -- Een set van links, bijv., ^expense-report (set[str]) -
Posting Attributen Deze kolommen zijn specifiek voor elke individuele posting line.
SELECT
account, -- De account naam (str)
position, -- Het volledige bedrag, inclusief units en cost (Position)
units, -- Het aantal en de valuta van de posting (Amount)
cost, -- De cost basis van de posting (Cost)
price, -- De prijs die in de posting is gebruikt (Amount)
weight, -- De positie geconverteerd naar zijn cost basis (Amount)
balance -- Het lopende totaal van units in de account (Inventory)
Query Functies
BQL bevat een suite van functies voor aggregatie en data transformatie, net als SQL.
Aggregatie Functies
Aggregatie functies vatten data samen over meerdere rijen. Wanneer gebruikt met GROUP BY, bieden ze gegroepeerde samenvattingen.
-- Tel het aantal postings
SELECT COUNT(*)
-- Tel de waarde van alle postings op (geconverteerd naar een gemeenschappelijke valuta)
SELECT SUM(position)
-- Vind de datum van de eerste en laatste transactie
SELECT FIRST(date), LAST(date)
-- Vind de minimum en maximum position values
SELECT MIN(position), MAX(position)
-- Groepeer op account om een som voor elk te krijgen
SELECT account, SUM(position) GROUP BY account
Position/Inventory Functies
De position kolom is een samengesteld object. Deze functies laten je specifieke delen ervan extraheren of de marktwaarde ervan berekenen.
-- Extraheer alleen het aantal en de valuta van een positie
SELECT UNITS(position)
-- Toon de totale cost van een positie
SELECT COST(position)
-- Toon de positie geconverteerd naar zijn cost basis (handig voor investeringen)
SELECT WEIGHT(position)
-- Bereken de marktwaarde met behulp van de laatste price data
SELECT VALUE(position)
Je kunt deze combineren voor krachtige rapporten. Bijvoorbeeld, om de totale cost en huidige marktwaarde van je investeringsportfolio te zien:
SELECT
account,
COST(SUM(position)) AS total_cost,
VALUE(SUM(position)) AS market_value
FROM
account ~ "Assets:Investments"
GROUP BY
account
Geavanceerde Functies
Naast basis SELECT statements, biedt BQL gespecialiseerde commands voor veelvoorkomende financiële rapporten.
Balance Rapporten
Het BALANCES statement genereert een balance sheet of income statement voor een specifieke periode.
-- Genereer een simpele balance sheet per het begin van 2024
BALANCES FROM close ON 2024-01-01
WHERE account ~ "^Assets|^Liabilities"
-- Genereer een income statement voor het 2024 fiscale jaar
BALANCES FROM
OPEN ON 2024-01-01
CLOSE ON 2024-12-31
WHERE account ~ "^Income|^Expenses"
Journal Rapporten
Het JOURNAL statement toont de gedetailleerde activiteit voor een of meer accounts, vergelijkbaar met een traditionele ledger view.
-- Toon alle activiteit in je checking account tegen zijn originele cost
JOURNAL "Assets:Checking" AT COST
-- Toon alle 401k transacties, en toon alleen de units (shares)
JOURNAL "Assets:.*:401k" AT UNITS
Print Operaties
Het PRINT statement is een debugging tool dat volledige, overeenkomende transacties in hun originele Beancount file format output.
-- Print alle investerings-gerelateerde transacties van 2024
PRINT FROM year = 2024
WHERE account ~ "Assets:Investments"
-- Vind een transactie op basis van zijn unieke ID (gegenereerd door sommige tools)
PRINT FROM id = "8e7c47250d040ae2b85de580dd4f5c2a"
Filter Expressies
Je kunt geavanceerde filters bouwen met behulp van logische operatoren (AND, OR), regular expressions (~) en vergelijkingen.
-- Vind alle travel expenses van de tweede helft van 2024
SELECT * FROM
year = 2024 AND month >= 6
WHERE account ~ "Expenses:Travel"
-- Vind alle transacties gerelateerd aan een vacation of business
SELECT * FROM
"vacation-2024" IN tags OR
"business-trip" IN links