2015-06-12 20 views
8

Làm cách nào để ghi truy vấn bằng các chức năng cửa sổ và chọn tất cả các trường trong QueryDSL? Trong các tài liệu có là một ví dụ như thế này:QueryDSL Các chức năng cửa sổ

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

nhưng tôi cần phải tạo ra một truy vấn như:

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 

Và là nó có thể làm điều đó với JPAQuery?

Trả lời

8

JPAQuery chỉ hỗ trợ các expressivity của JPQL, vì vậy chức năng cửa sổ không được hỗ trợ, nhưng phân trang nên việc sử dụng

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

Trong trường hợp bạn cần phải sử dụng chức năng cửa sổ và bạn cần employee.name và employee.id ra này nên làm việc

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

Và cách thực hiện với SQLQuery? – matteobarbieri

+0

Đối với SQLQuery, cách tốt nhất là làm như vậy, vì việc xử lý giới hạn/bù đắp được ánh xạ nội bộ vào chức năng phân trang do công cụ SQL cung cấp. –

+1

Ok cảm ơn. Trên thực tế trong mã của tôi, tôi cần xếp hạng và không được xếp hạng, vì vậy giới hạn sẽ không hoạt động. Có cách nào để tạo truy vấn giống như truy vấn tôi đã đăng không? – matteobarbieri

0

Như được viết bởi @timo chức năng Window (cấp bậc, row_number) không được hỗ trợ bởi JPQL (JPA 2.1 phiên bản) và do đó bởi JPAQuery (QueryDsl JPA 4.1.4).

Bạn tuy nhiên có thể viết lại truy vấn của bạn vì vậy đó là không sử dụng cấp bậc trên():

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 

này được hỗ trợ bởi JPAQuery, nó có thể đi như thế này.

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); 
Các vấn đề liên quan