java - 在 querydsl 中选择每组最大的元素

标签 java sql jpa greatest-n-per-group querydsl

我有一个大致如下所示的 sql 表:

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

对于每种类型,我想检索具有最大值的行。这是我的预期结果:

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

在 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

但是我找不到使用 QueryDSL(版本 4)表达相同内容的方法。我试过这个:

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

但是 innerJoin()(和其他连接方法)只接受一个表达式作为参数,而不是另一个查询。 from() 也是如此。

最佳答案

子查询可以以 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());

请注意,此查询可能效率很低。

关于java - 在 querydsl 中选择每组最大的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58344766/

相关文章:

java - 不兼容的类型 : java. lang.Object 无法转换为 T

java - Tomcat 图标有问题

java - 如何在sql表中存储jsp文件并执行它?

hibernate - 使用 native 查询的 JPA(Hibernate) 和 postgresql 批量插入

java - spring jpa疑惑

java - 使用 Spring Data 在 Spring Boot 应用程序中 Autowiring DynamoDB 存储库

java - 如何组合Switch语句?

from 子句中具有不同表的 SQL 更新语句

sql - 如何从pgsql中的列表中选择数据

java - 尝试从父实体java类中删除记录