我有一个大致如下所示的 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/