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



我想使用jooq:实现这个查询

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

现在,jooq提供了fetchGroups((,它完美地将值映射到Map<字符串,列表>

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

但是,我不知道如何按照sum((值对返回的结果进行排序。

当您使用ResultQuery.fetchGroups()时,您在Java中对结果集进行分组,而不是在SQL中。这有很多合法的情况,但在您的情况下,我认为您应该直接在SQL中执行所有操作,假设您使用的是PostgreSQL,因为您已经在SQL查询中使用了ARRAY_AGG()。只需写:

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[]类型,您可以在ResultQuery.collect()上使用JDKCollectorAPI,而不是

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())
));

相关内容

  • 没有找到相关文章

最新更新