A common confusion when writing SQL GROUP BY is the logical order of SQL operations. While syntactically, SELECT seems to appear before GROUP BY, logically the order is inverse. This means that you cannot really reference columns in the SELECT clause from the GROUP BY clause.
Some dialects may have implemented exceptions "for convenience", but this is generally very confusing. I recommend not doing that.
But to solve your problem:
Producing the SQL you wanted to produce
While in your original SQL query, you used aliases for your two expressions (AS year and AS month), in the jOOQ query you did not. I recommend you use aliases as well, and assign the column expressions to local variables for reuse in the groupBy() clause:
Field<?> month = DSL.month(DSL.date(TRANSACTION.CREATION_DATE)).as("month");
Field<?> year = DSL.year(DSL.date(TRANSACTION.CREATION_DATE)).as("year");
dsl.select(month, year, DSL.sum(TRANSACTION.VALUE))
.from(TRANSACTION)
.groupBy(month, year)
.fetch();
Aliased columns produce the full declaration in the SELECT clause, but only the alias in all other clauses, so this does exactly what you wanted:
SELECT
month(date(transaction.creation_date)) as month,
year(date(transaction.creation_date)) as year
sum(transaction.value)
FROM transaction
GROUP BY
month,
year;
A better SQL statement according to the logical order of operations
If you want your SQL to remain portable and correct according to the logical order of SQL operations I've mentioned, I recommend you write this instead:
Field<?> month = DSL.month(DSL.date(TRANSACTION.CREATION_DATE));
Field<?> year = DSL.year(DSL.date(TRANSACTION.CREATION_DATE));
dsl.select(month.as("month"), year.as("year"), DSL.sum(TRANSACTION.VALUE))
.from(TRANSACTION)
.groupBy(month, year)
.fetch();
Notice that I've moved the aliasing to the SELECT clause, whereas in the GROUP BY clause, I'm now referencing the full column expressions. This will produce thef ollowing query:
SELECT
month(date(transaction.creation_date)) as month,
year(date(transaction.creation_date)) as year
sum(transaction.value)
FROM transaction
GROUP BY
month(date(transaction.creation_date)),
year(date(transaction.creation_date));
The full expressions are now expanded into the GROUP BY clause, without you having to repeat them manually.