I need a way to sort based on date, with all rows of a certain type to be grouped last (but also sorted by date).
For instance, suppose I have a DB column where values can take on ["A", "B", "C"]. In the same table, there is also a dateCreated column.
I want all rows with "A" to be last and all rows (including those within group A) to be sorted by date created (ascending for simplicity sake)
For instance, if I had the rows:
ID | enum | dateCreated |
---|---|---|
1 | A | 2020-01-01 |
2 | A | 2020-01-03 |
3 | A | 2020-01-02 |
4 | B | 2020-02-03 |
5 | B | 2020-02-01 |
6 | C | 2020-02-02 |
The resulting order should be:
5,6,4,1,3,2
To explain, all of the non-A rows come first, ordered by date. Then all of the A rows, also ordered by date.
I see the SO post QueryDsl orderBy specific string values which almost provides what I need, but it is unfortunately not nuanced enough for my use case.
CodePudding user response:
You can order by a boolean expresion. Booleans order false to true naturally, so you can just sort ascending.
.orderBy(enum.eq("A").asc(), created.asc())
CodePudding user response:
I ended up finding a working solution with something like:
private OrderSpecifier<Integer> orderByEnum() {
NumberExpression<Integer> cases = new CaseBuilder()
.when(QTable.table.enum.eq("A"))
.then(2)
.otherwise(1);
return new OrderSpecifier<>(Order.ASC, cases);
}
I added that to a order specifier array like so:
OrderSpecifier<?>[] order = new OrderSpecifier[] {
orderByEnum(),
QTable.table.dateCreated.asc()
};
And then I passed the order specifier array to the query with
queryFactory.select(...)
.from(...)
.where(...)
.orderBy(order);
It looks like this got me what I needed. Just had to break the problem down into individual components and add that to an order specifier array.