Home > Blockchain >  QueryDsl orderBy some enums and date
QueryDsl orderBy some enums and date

Time:08-11

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.

  • Related