如何使用jooq获取按聚合值排序的组

bgibtngc  于 2021-06-30  发布在  Java
关注(0)|答案(1)|浏览(562)

我想用jooq实现这个查询:

SELECT bank_id, array_agg(id)
FROM aggregative_line_item
GROUP BY bank_id
ORDER BY sum(amount) desc;

现在,jooq提供了fetchgroups(),它将值完美地Map到map<string,list>

create.selectFrom(aggregative_line_item)
            .fetchGroups(aggregative_line_item.bank_id, aggregative_line_item.id);

但是,我不明白如何按sum()值对返回的结果排序。

xv8emn3q

xv8emn3q1#

当你使用 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[] 类型,您可以使用jdk Collector 上的API 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())
      ));

相关问题