Я хочу преобразовать этот SQL-запрос в JOOQ DSL.
select "p".*, array_agg("pmu") as projectmemberusers
from "Projects" as "p"
join "ProjectMemberUsers" as "pmu" on "pmu"."projectId" = "p"."id"
group by "p"."id";
В настоящее время я пробовал делать что-то подобное с помощью JOOQ:
val p = PROJECTS.`as`("p")
val pmu = PROJECTMEMBERUSERS.`as`("pmu")
val query = db.select(p.asterisk(), DSL.arrayAgg(pmu))
.from(p.join(pmu).on(p.ID.eq(pmu.PROJECTID)))
.groupBy(p.ID)
Это не работает, потому что DSL.arrayAgg
ожидает на входе что-то типа Field<T>
.
Я новичок в JOOQ и не специалист по SQL. Приветствуются подробные объяснения и предложения по улучшению.
Хм, запрос действительно работает для меня. Может быть, взгляните на этот blog.jooq.org/2017/01/12/… (внизу страницы «Альтернативные синтаксисы: PostgreSQL»)
@AlexeySoshin: Вы ссылаетесь на таблицу в проекции для создания вложенных записей в PostgreSQL.
@LukasEder, да, уже подтвердил это, хотя это плохо документировано в PostgreSQL. Верно ли мое предположение, что он все еще не поддерживается jOOQ?
@AlexeySoshin: Верно, в настоящее время не поддерживается. Можно сравнить две таблицы t1 = t2
, но пока не спроецировать их. Вложенные записи все еще экспериментальны в jOOQ.
@LukasEder есть ли альтернативный синтаксис? Планируете ли вы поддержать это в каком-нибудь будущем выпуске?
Во-первых, синтаксис действительно работает, проверено в SQL Fiddle: http://sqlfiddle.com/#!17/e45b7/3
Но это подробно не задокументировано: https://www.postgresql.org/docs/9.5/static/functions-aggregate.htmlhttps://www.postgresql.org/docs/current/static/rowtypes.html#ROWTYPES-USAGE
Вероятно, поэтому jOOQ не поддерживает это в настоящее время: https://github.com/jOOQ/jOOQ/blob/master/jOOQ/src/main/java/org/jooq/impl/DSL.java#L16856
Единственный синтаксис, который в настоящее время будет работать, - это одно поле: DSL.arrayAgg(pmu.field(1))
.
Вы ищете способ выразить "анонимные" вложенные записи PostgreSQL через jOOQ API, аналогично тому, что запрашивается в этом запросе функции: https://github.com/jOOQ/jOOQ/issues/2360
В настоящее время это невозможно в jOOQ API версии 3.11, но определенно будет в будущем.
Вы можете попробовать использовать экспериментальные методы DSL.rowField()
в представлении Row[N]<...>
вашего типа таблицы. Это может работать, а может и не работать, так как эта функция в настоящее время не поддерживается.
Обходной путь - создать тип:
create type my_type as (...) -- Same row type as your table
И вид:
create view x as
select "p".*, array_agg("pmu"::my_type) as projectmemberusers
from "Projects" as "p"
join "ProjectMemberUsers" as "pmu" on "pmu"."projectId" = "p"."id"
group by "p"."id";
А затем воспользуйтесь генератором кода, чтобы подобрать получившийся тип.
Как я могу получить представление типа таблицы в Row[N]<...>
? Пробовал делать DSL.arrayAgg(DSL.rowField(pmu.fieldsRow()))
. Но rowField(..)
нельзя вызвать с этим параметром.
@TobiasMarschall: Сгенерированные таблицы содержат методы row()
. Это поможет? Если нет, не стесняйтесь задавать новый вопрос
Я создал дополнительный вопрос. stackoverflow.com/questions/52003995/…
Честно говоря, я не понимаю, как работает исходный запрос.
array_agg()
должен получить столбец, а вы передаете ему псевдоним таблицы. Что я скучаю?