简体   繁体   English

select querydsl 中每组的最大元素

[英]select greatest element per group in querydsl

I have a sql table that looks roughly like this:我有一个 sql 表,大致如下所示:

+-----+------+-------+
|  id | type | value |
+-----+------+-------+
|  1  |   X  |   20  |
|  2  |   X  |   30  |
|  3  |   Y  |  200  |
|  4  |   Y  |  500  |
|  5  |   Y  |  300  |
|  6  |   Z  |    5  |
+-----+------+-------+

For each type I want to retrieve the row with the maximum value.对于每种类型,我想检索具有最大值的行。 This is my expected result:这是我的预期结果:

+-----+------+
|  id | type |
+-----+------+
|  2  |   X  | <-- had value = 30
|  4  |   Y  | <-- had value = 500
|  6  |   Z  | <-- had value = 5
+-----+------+

In SQL, this can be expressed as follows (given that for each type there aren't two entries with the same value, which I can rule out):在 SQL 中,这可以表示如下(假设每种类型没有两个具有相同值的条目,我可以排除):

select t1.id, t1.type from T t1
inner join (
  select t2.type, max(t2.value) as max_value from T t2
  group by t2.type
) on t1.type = t2.type
  and t1.value = max_value

However I cannot find a way to express the same using QueryDSL (version 4).但是,我找不到使用 QueryDSL(第 4 版)表达相同内容的方法。 I tried this:我试过这个:

final JPQLQuery<Tuple> subquery = JPAExpressions
    .from(q2)
    .select(q2.type, q2.value.max())
    .groupBy(q2.type);
final JPQLQuery<Tuple> query = JPAExpressions
    .from(q1)
    .select(q1.id, q1.type)
    .from(q1)
    .innerJoin(subquery) // <-- not allowed
    .on(q1.type.eq(q2.type), q1.value.eq(q2.value.max()));

But innerJoin() (and other join methods) only take an expression as parameter, not another query.但是innerJoin() (和其他连接方法)只接受一个表达式作为参数,而不是另一个查询。 The same goes for from() . from()也是如此。

The subquery can be put into the outer query's where clause in the form of an exists -expression:子查询可以以exists表达式的形式放入外部查询的where子句中:

final JPQLQuery<Tuple> subquery = JPAExpressions
    .from(q2)
    .select(q2.type, q2.value.max())
    .groupBy(q2.type);
final JPQLQuery<Tuple> query = JPAExpressions
    .from(q1)
    .select(q1.id, q1.type)
    .from(q1)
    .where(subquery
        .having(q1.type.eq(q2.type), q1.value.eq(q2.value.max()))
        .exists());

Note that this query might be quite inefficient.请注意,此查询可能效率很低。

In order to get the top 1 element, you can use:为了获得前 1 个元素,您可以使用:

JPAExpressions.selectFrom(table)
    .select(table.dateTimeColumn.max())

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

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