#java #postgresql #jooq
#java #postgresql #jooq
Вопрос:
Я хочу отфильтровать результаты по определенному значению в агрегированном массиве в запросе.
Вот небольшое описание проблемы. Раздел принадлежит саду. Сад принадлежит округу, а округ принадлежит провинции. У пользователей есть несколько разделов. Эти разделы принадлежат их садам, и они относятся к их районам, а они — к провинции.
Я хочу получить идентификаторы пользователей, которые имеют значение 2 в массиве district. Я пытался использовать любой оператор, но он не работает должным образом. (синтаксическая ошибка) Будем признательны за любую помощь.
ps: Это возможно при написании с использованием обычного SQL
rs = dslContext.select(
field("user_id"),
field("gardens_array"),
field("province_array"),
field("district_array"))
.from(table(select(
arrayAggDistinct(field("garden")).as("gardens_array"),
arrayAggDistinct(field("province")).as("province_array"),
arrayAggDistinct(field("distict")).as("district_array"))
.from(table("lst.user"))
.leftJoin(table(select(
field("section.user_id").as("user_id"),
field("garden.garden").as("garden"),
field("garden.province").as("province"),
field("garden.distict").as("distict"))
.from(table("lst.section"))
.leftJoin("lst.garden")
.on(field("section.garden").eq(field("garden.garden")))
.leftJoin("lst.district")
.on(field("district.district").eq(field("garden.district")))).as("lo"))
.on(field("user.user_id").eq(field("lo.user_id")))
.groupBy(field("user.user_id"))).as("joined_table"))
.where(val(2).equal(DSL.any("district_array"))
.fetch()
.intoResultSet();
Комментарии:
1. Нет причин для того, чтобы этот вопрос получил 3 отрицательных отзыва. Насколько я могу судить, это совершенно законно…
Ответ №1:
Вызывается ваш код DSL.any(T...)
, который соответствует выражению any(?)
в PostgreSQL, где значением привязки в вашем случае является String[]
. Но вы не хотите, чтобы "district_array"
было значением привязки, вы хотите, чтобы это была ссылка на столбец. Итак, либо вы присваиваете свое arrayAggDistinct()
выражение локальной переменной и повторно используете его, либо вы повторно используете свое field("district_array")
выражение или реплицируете его:
val(2).equal(DSL.any(field("district_array", Integer[].class)))
Обратите внимание, что обычно хорошей идеей является четкое указание типов данных (например, Integer[].class
) при работе с простым SQL templating API или, что еще лучше, использовать генератор кода.
Комментарии:
1. Не удается разрешить метод ‘equal(org.jooq. QuantifiedSelect<org.jooq. Record1<T>>) Это точная ошибка, которую я получаю. Спасибо за предложения.
2. не могли бы вы, пожалуйста, проверить синтаксис?
3. @AshanTharindu, я допустил ошибку, это должно быть
Integer[]
из-за того, что вы используетеarrayAgg()
, но что касается ошибок компиляции, это не должно иметь значения