Распространенная путаница при записи SQL GROUP BY
- логический порядок SQL операций . Хотя синтаксически SELECT
кажется раньше GROUP BY
, логически порядок обратный. Это означает, что вы не можете ссылаться на столбцы в предложении SELECT
из предложения GROUP BY
.
В некоторых диалектах могут быть реализованы исключения «для удобства», но это, как правило, очень запутанно. Я рекомендую этого не делать.
Но для решения вашей проблемы:
Создание SQL, которое вы хотели произвести
В то время как в исходном запросе SQL вы использовали псевдонимы для ваших двух выражений (AS year
и AS month
), в запросе jOOQ вы этого не сделали. Я также рекомендую использовать псевдонимы и назначать выражения столбцов локальным переменным для повторного использования в предложении groupBy()
:
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();
Столбцы с псевдонимами создают полное объявление в предложении SELECT
, но только псевдоним во всех других пунктах, так что это делает именно то, что вы хотели:
SELECT
month(date(transaction.creation_date)) as month,
year(date(transaction.creation_date)) as year
sum(transaction.value)
FROM transaction
GROUP BY
month,
year;
Лучше SQL оператор в соответствии с логическим порядком операций
Если вы хотите, чтобы ваш SQL оставайтесь переносимыми и корректными в соответствии с логическим порядком операций SQL, которые я упомянул, я рекомендую написать это вместо:
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();
Обратите внимание, что я перенес псевдоним в предложение SELECT
, тогда как в предложении GROUP BY
я сейчас ссылаюсь на полные выражения столбцов. Это приведет к следующему запросу:
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));
Полные выражения теперь развернуты в предложение GROUP BY
, без необходимости повторять их вручную.