Я хочу реализовать этот запрос с помощью jooq: SELECT bank_id, array_agg (id) FROM aggregative_line_item GROUP BY bank_id ORDER BY sum (amount) desc; Теперь jooq предоставляет fetchGroups (), который отлично отображает ...

1
Gene Zeiniss 13 Дек 2020 в 12:15

1 ответ

Лучший ответ

Когда вы используете ResultQuery.fetchGroups(), то вы группируете наборы результатов в Java, а не в SQL. Для этого есть много законных случаев, но в вашем случае, я думаю, вам следует делать все напрямую в SQL, предполагая, что вы используете PostgreSQL, потому что вы уже использовали ARRAY_AGG() в своем запросе SQL. Просто пиши:

Result<Record2<String, Integer[]>> result =
create.select(AGGREGATIVE_LINE_ITEM.BANK_ID, arrayAgg(AGGREGATIVE_LINE_ITEM.ID))
      .from(AGGREGATIVE_LINE_ITEM)
      .groupBy(AGGREGATIVE_LINE_ITEM.BANK_ID)
      .orderBy(sum(AGGREGATIVE_LINE_ITEM.AMOUNT).desc())
      .fetch();

Это предполагает обычный статический импорт, в том числе:

import static org.jooq.impl.DSL.*;

Результат не совсем в той форме, которую вы искали, но вы все равно можете вызвать fetchMap() для получения результата, например

Map<String, Integer[]> map = result.fetchMap(
  AGGREGATIVE_LINE_ITEM.BANK_ID, 
  arrayAgg(AGGREGATIVE_LINE_ITEM.ID)
);

Или вместо того, чтобы повторять выражения, вы можете назначить их локальным переменным и повторно использовать:

Field<String> key = AGGREGATIVE_LINE_ITEM.BANK_ID;
Field<Integer[]> value = arrayAgg(AGGREGATIVE_LINE_ITEM.ID);

// And then:
Map<String, Integer[]> map = 
create.select(key, value)
      .from(AGGREGATIVE_LINE_ITEM)
      .groupBy(AGGREGATIVE_LINE_ITEM.BANK_ID)
      .orderBy(sum(AGGREGATIVE_LINE_ITEM.AMOUNT).desc())
      .fetchMap(key, value);

Тем не менее, если вы предпочитаете тип List<Integer> типу Integer[], вы можете использовать API JDK Collector на ResultQuery.collect() вместо этого:

Map<String, List<Integer>> map = 
create.select(AGGREGATIVE_LINE_ITEM.BANK_ID, arrayAgg(AGGREGATIVE_LINE_ITEM.ID))
      .from(AGGREGATIVE_LINE_ITEM)
      .groupBy(AGGREGATIVE_LINE_ITEM.BANK_ID)
      .orderBy(sum(AGGREGATIVE_LINE_ITEM.AMOUNT).desc())
      .collect(Collectors.toMap(
         r -> r.value1(),
         r -> Arrays.asList(r.value2())
      ));
3
Lukas Eder 13 Дек 2020 в 12:08