2015-06-12 6 views
8

Wie kann ich eine Abfrage mit Fensterfunktionen schreiben und alle Felder in QueryDSL auswählen? In der Dokumentation gibt es ein Beispiel wie folgt aus:QueryDSL Window-Funktionen

query.from(employee) 
.list(SQLExpressions.rowNumber() 
    .over() 
    .partitionBy(employee.name) 
    .orderBy(employee.id)); 

aber ich brauche eine Abfrage wie zu generieren:

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 

Und ist es möglich, sie mit JPAQuery zu tun?

Antwort

8

JPAQuery unterstützt nur die Expressivität von JPQL, so Fensterfunktionen nicht unterstützt werden, aber Paging sollte

query.from(employee).orderBy(employee.id).limit(1) 

Falls Sie Fensterfunktionen müssen mit arbeiten verwenden, und Sie müssen employee.name und employee.id aus dies sollte

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

Und wie es mit SQLQuery zu tun? – matteobarbieri

+0

Für SQLQuery ist es am besten, das gleiche zu tun, da die Limit/Offset-Behandlung intern der von der SQL-Engine bereitgestellten Paging-Funktionalität zugeordnet wird. –

+1

Ok danke. Eigentlich brauche ich in meinem Code Rang und nicht Nummer, also wird Limit nicht funktionieren. Gibt es eine Möglichkeit, eine Abfrage wie die, die ich gepostet habe, zu generieren? – matteobarbieri

0

arbeitet Wie @timo Fensterfunktionen geschrieben (Rang, row_number) nicht von JPQL (JPA Version 2.1) und damit von JPAQuery (QueryDsl JPA 4.1.4) unterstützt.

Sie können jedoch neu schreiben Sie Ihre Abfrage, damit zu verwenden ist nicht Rang über():

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 

Das von JPAQuery unterstützt wird, geht es wohl so.

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