如何从一个组中获得第一个结果(Jooq)

问题描述 投票:1回答:1

我的要求是获取一个标识符列表,每个标识符可以指向多条记录,并返回每个标识符的最新记录。

这似乎可以通过以下组合来实现。orderBy(date, desc)fetchGroups() 上的标识符列。然后我使用 values() 来获取结果对象。

此时,我想要每个结果对象中的第一个值。我可以用 get(0) 来获取列表中的第一个值,但这似乎是作弊。是否有更好的方法从一个 Result 对象?

java sql orm jooq
1个回答
2
投票

你要写一个top-1-per-category查询,这是一个特殊情况下的 按类别查询. 大多数在SQL中产生这种行为的语法也被jOOQ支持。你不应该在客户端中使用分组,因为你会把所有多余的数据从服务器转移到客户端,这相当于每个组的剩余结果。

一些例子。

标准SQL(当窗口函数被支持时)

Field<Integer> rn = rowNumber().over(T.DATE.desc()).as("rn");

var subquery = table(
    select(T.fields())
   .select(rn)
   .from(T)
).as("subquery");

var results = 
ctx.select(subquery.fields(T.fields())
   .from(subquery)
   .where(subquery.field(rn).eq(1))
   .fetch();

Teradata和H2(可望仿效)

var results = 
ctx.select(T.fields())
   .from(T)
   .qualify(rowNumber().over(T.DATE.desc()).eq(1))
   .fetch();

PostgreSQL

var results = 
ctx.select(T.fields())
   .distinctOn(T.DATE)
   .from(T)
   .orderBy(T.DATE.desc())
   .fetch();

甲骨文

var results = 
ctx.select(
      T.DATE, 
      max(T.COL1).keepDenseRankFirstOrderBy(T.DATE.desc()).as(T.COL1),
      max(T.COL2).keepDenseRankFirstOrderBy(T.DATE.desc()).as(T.COL2),
      ...
      max(T.COLN).keepDenseRankFirstOrderBy(T.DATE.desc()).as(T.COLN))
   .from(T)
   .groupBy(T.DATE)
   .fetch();
© www.soinside.com 2019 - 2024. All rights reserved.