Использование PosgreSQL array_agg с псевдонимом соединения в JOOQ DSL

Я хочу преобразовать этот 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. Приветствуются подробные объяснения и предложения по улучшению.

Честно говоря, я не понимаю, как работает исходный запрос. array_agg() должен получить столбец, а вы передаете ему псевдоним таблицы. Что я скучаю?

Alexey Soshin 08.08.2018 22:04

Хм, запрос действительно работает для меня. Может быть, взгляните на этот blog.jooq.org/2017/01/12/… (внизу страницы «Альтернативные синтаксисы: PostgreSQL»)

Tobias Marschall 08.08.2018 22:08

@AlexeySoshin: Вы ссылаетесь на таблицу в проекции для создания вложенных записей в PostgreSQL.

Lukas Eder 09.08.2018 10:53

@LukasEder, да, уже подтвердил это, хотя это плохо документировано в PostgreSQL. Верно ли мое предположение, что он все еще не поддерживается jOOQ?

Alexey Soshin 09.08.2018 10:57

@AlexeySoshin: Верно, в настоящее время не поддерживается. Можно сравнить две таблицы t1 = t2, но пока не спроецировать их. Вложенные записи все еще экспериментальны в jOOQ.

Lukas Eder 09.08.2018 12:16

@LukasEder есть ли альтернативный синтаксис? Планируете ли вы поддержать это в каком-нибудь будущем выпуске?

Tobias Marschall 09.08.2018 14:55
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
3
6
1 020
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Во-первых, синтаксис действительно работает, проверено в 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, но определенно будет в будущем.

Обходной путь 1

Вы можете попробовать использовать экспериментальные методы DSL.rowField() в представлении Row[N]<...> вашего типа таблицы. Это может работать, а может и не работать, так как эта функция в настоящее время не поддерживается.

Обходной путь 2

Обходной путь - создать тип:

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(..) нельзя вызвать с этим параметром.

Tobias Marschall 24.08.2018 12:55

@TobiasMarschall: Сгенерированные таблицы содержат методы row(). Это поможет? Если нет, не стесняйтесь задавать новый вопрос

Lukas Eder 24.08.2018 13:13

Я создал дополнительный вопрос. stackoverflow.com/questions/52003995/…

Tobias Marschall 24.08.2018 13:58

Другие вопросы по теме