如何使用窗口函数编写查询并选择QueryDSL中的所有字段? 在文档中有一个这样的例子:
query.from(employee)
.list(SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id));
但我需要生成一个类似的查询:
SELECT * FROM
(SELECT employee.name, employee.id, row_number()
over(partition BY employee.name
ORDER BY employee.id)
FROM employee) AS sub
WHERE row_number = 1
是否可以使用JPAQuery进行此操作?
答案 0 :(得分:11)
JPAQuery仅支持JPQL的表达性,因此不支持窗口函数,但是分页应该可以使用
query.from(employee).orderBy(employee.id).limit(1)
如果您需要使用窗口函数,并且需要employee.name和employee.id,这应该可以正常工作
NumberExpression<Long> rowNumber = SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id).as("rowNumber");
query.select(employee.name, employee.id)
.from(SQLExpressions.select(employee.name, employee.id, rowNumber)
.from(employee).as(employee))
.where(Expressions.numberPath(Long.class, "rowNumber").eq(1L))
.fetch();
答案 1 :(得分:0)
由 @timo 编写的JPQL(JPA 2.1版本)和JPAQuery(QueryDsl Jpa 4.1.4)不支持窗口函数(rank,row_number)。
但是,你可以重写你的查询,这样就不会使用rank over():
select a.* from employees a
where
(
select count(*) from employees b
where
a.department = b.department and
a.salary <= b.salary
) <= 10
order by salary DESC
这是JPAQuery支持的,它可能是这样的。
final BooleanBuilder rankFilterBuilder =
new BooleanBuilder(employee.department.eq(employee2.department));
rankFilterBuilder.and(employee.salary.loe(employee2.salary));
query.from(employee)
.where(JPAExpressions.selectFrom(employee2)
.where(rankFilterBuilder)
.select(employee2.count())
.loe(10))
.orderBy(employee.salary);