Is it possible to do my custom order by using criteria query or jpql in Java? In my table, I have a column – number type(for now, this column includes numbers such as 1
, 2
, 3
, 5
, 10
). I would like to sort result in this order 2
, 5
, 1
, 10
, 3
.
CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<MyEntity> cq = cb.createQuery(MyEntity.class); Root<MyEntity> root = cq.from(MyEntity.class); cq.select(root); cq.where(cb.equal(root.get("someMyFields"), "myExpectedFieldValue")); cq.orderBy(cb.asc(root.get("myNumberField"))); // how can I sort result in this order 2, 5, 1, 10, 3? TypedQuery<MyEntity> query = em.createQuery(cq); query.setFirstResult(0); query.setMaxResults(200); return query.getResultList();
How can I do it?
Advertisement
Answer
You have to use a CASE
expression in your ORDER BY
clause to implement this kind of “sort indirection”. In SQL and JPQL, this would be:
ORDER BY CASE myNumberField WHEN 2 THEN 1 WHEN 5 THEN 2 WHEN 1 THEN 3 WHEN 10 THEN 4 WHEN 3 THEN 5 ELSE 6 END
With the criteria API, using CriteriaBuilder.selectCase()
cq.orderBy( qb.selectCase(root.get("myNumberField")) .when(qb.literal(2), qb.literal(1)) .when(qb.literal(5), qb.literal(2)) .when(qb.literal(1), qb.literal(3)) .when(qb.literal(10), qb.literal(4)) .when(qb.literal(3), qb.literal(5)) .otherwise(qb.literal(6)) .getExpression() .asc());
Of course, a much better solution is to normalise these values in a separate table that you can join just for the ordering:
SELECT * FROM t JOIN orderings o ON t.myNumberField = o.myNumberField ORDER BY o.orderDefinition