简体   繁体   English

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

[英]How to get the first result from a group (Jooq)

My requirement is to take a list of identifiers, each of which could refer to multiple records, and return the newest record per identifier.我的要求是获取一个标识符列表,每个标识符都可以引用多个记录,并返回每个标识符的最新记录。

This would seem to be doable with a combination of orderBy(date, desc) and fetchGroups() on the identifier column.这似乎可以通过标识符列上的orderBy(date, desc)fetchGroups()的组合来实现。 I then use values() to get the Result objects.然后我使用values()来获取 Result 对象。

At this point, I want the first value in each result object.此时,我想要每个结果 object 中的第一个值。 I can do get(0) to get the first value in the list, but that seems like cheating.我可以做get(0)来获得列表中的第一个值,但这似乎是作弊。 Is there a better way to get that first result from a Result object?有没有更好的方法从Result object 中获得第一个结果?

You're going to write a top-1-per-category query, which is a special case of a top-n-per-category query .您将编写一个 top-1-per-category 查询,这是top-n-per-category 查询的一个特例。 Most syntaxes that produce this behaviour in SQL are supported by jOOQ as well. jOOQ 也支持在 SQL 中产生这种行为的大多数语法。 You shouldn't use grouping in the client, because you'd transfer all the excess data from the server to the client, which corresponds to the remaining results per group.您不应该在客户端中使用分组,因为您会将所有多余的数据从服务器传输到客户端,这对应于每个组的剩余结果。

Some examples:一些例子:

Standard SQL (when window functions are supported)标准 SQL(支持 window 功能时)

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 and H2 ( we might emulate this soon ) Teradata 和 H2(我们可能很快会效仿

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

PostgreSQL PostgreSQL

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

Oracle Oracle

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM