beanquery icon indicating copy to clipboard operation
beanquery copied to clipboard

GROUP BY and financial year

Open tbm opened this issue 5 years ago • 2 comments
trafficstars

SELECT YEAR, SUM(position) WHERE account ~ '^Income' GROUP BY YEAR ORDER BY YEAR

Unfortunately, the financial year is not the calendar year.

It would be nice for BQL to somehow have the concept of a financial year.

(FWIW, Fava has support for financial years)

tbm avatar May 25 '20 04:05 tbm

It would be sufficient to provide a function that return the fiscal year given a dare, then you can simply do

SELECT fiscal_year(date) AS fy, sum(position) WHERE root(account) = 'Income' GROUP BY fy ORDER BY fy

However, the fiscal year end is not an universal definition. Assuming for simplicity that we care only about fiscal years that have a one calendar year duration, the function would need to take the fiscal year end or start date as a parameter, probably as a two integers for month and day, but this results in quite an ugly interface:

fiscal_year(date, 3, 5)

I don't have better ideas.

dnicolodi avatar Mar 31 '22 16:03 dnicolodi

Another approach could be a truncate() function similar to the PostgreSQL's date_trunc() https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC that would allow to extract different facets from a date: truncate(date, "fiscal-year"), truncate(date, "fiscal-quarter"), truncate(date, "quarter"), and a new option in Beancount to set the fiscal year rules, something like option "fiscal-year" "..." where "..." is the definition of the fiscal year in some suitable format.

Looking at the PostgreSQL documentation, if the fiscal year is uniform, also something like the date_bin() function could apply: date_bin("year", date, 2022-03-05). This has the advantage of not requiring an option in Beancount to set the fiscal year start.

dnicolodi avatar Apr 22 '22 12:04 dnicolodi

@tbm I just merged the implementation of the date_bin() BQL function, see #212. It is an extension of the standard SQL date_bin() function and it accepts binning strides with month and year units. Can you please check if it works for your use case? I imagine that something like

SELECT
  date_bin('1 year', date, 2024-06-01) as year,
  sum(position) 
WHERE
  root(account) = 'Income'
GROUP BY 1
ORDER BY 1

should work, replacing 2024-06-01 with the correct start of the fiscal year.

dnicolodi avatar Nov 11 '24 21:11 dnicolodi

I've done some tests and this seems to work as expected, thank you!

tbm avatar Nov 19 '24 04:11 tbm

Thanks for testing. The implementation of date_bin() for strides with month or longer units is a fairly naive increment in a loop (AFAIK, it is impossible to implement the general case in a more efficient way, and this is most likely why the SQL standard function does not allow strides with month or longer units, and I didn't put in the effort to check whether any common special case can optimized) thus I recommend to keep the origin as close as possible as the values to bin.

dnicolodi avatar Nov 19 '24 08:11 dnicolodi