Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort PageRequest on String as numeric value

I currently have a system in place which can filter and sort records in the database and return them as a Paged object. One of the lines is like this:

final PageRequest request = new PageRequest(this.pagingSettings.getPageNumber(),
            this.pagingSettings.getPageSize(), sortDirection, sortedBy);

This works correctly, but now I'm having the following situation. I'm trying to sort on a house number, which is a varchar in my Postgres database. For example, we have 1, 12, 111, 1004 but also 1A or 36-BASEMENT. When sorting on these (character) values, these would sort on: 1, 1004, 111, 12, 1A, ...

So, sortedBy is now a String, which in this case is houseNumber. I found out that using the ORDER BY argument ... ORDER BY NULLIF(regexp_replace(container_number, E'\\D', '', 'g'), '')::int"; in Postgres, the sorting would be exactly like I wanted: 1, 1A, 12, 111, ...

However, just changing the sortedBy String to sortedBy = "NULLIF(regexp_replace(container_number, E'\\D', '', 'g'), '')::int"; does not seem to work.

Does anyone have a suggestion on how to sort the character values in a PageRequest numerical, without changing the database?

like image 484
Joetjah Avatar asked Nov 09 '16 13:11

Joetjah


People also ask

How to sort a field with only numeric or string values?

If the field contains only numeric values, consider changing the data type of the field to Number or Currency. Use the following procedure if: The field contains only numeric values, but you do not want to change the data type of the field. The field contains both numeric and string values, but you want ignore the string values when sorting.

How do you sort numbers in access?

Numbers and strings stored in a Short Text (text) or Long Text (memo) field in Access are sorted alphabetically. In other words, numbers will be sorted based on the individual digits that make up the value, instead of on the numeric value.

How do I sort a customer id field?

It's a string field and it will sort as a string. Usually the trick is to make sure the customer id length is always the same. So you should have C00000109 instead of C0000109. Now what you can do instead is add a new column in the table for sorting and maintain proper values there.

How do you sort data if the value is not null?

If the value is not null, the IIf function calls the Val function to obtain the numeric equivalent. In the Sort cell, select Ascending or Descending. An ascending sort displays the record with the smallest value on top and the record with the largest value at the bottom. A descending sort does the opposite.


Video Answer


2 Answers

So basically you need to do two things:

  1. Implement custom comparator,
  2. Annotate the entity class.

Ad.1.

public class HouseComparator implements Comparator<House> {
    @Override
    public int compare(House h1, House h2) {

        String s1 = h1.getHouseNumber().split("[^0-9]")[0];
        String s2 = h2.getHouseNumber().split("[^0-9]")[0];

        return s1.compareTo(s2);
    }
}

You need to add some better handling of your cases. The above comparator says, that h1 is less than h2 when it begins with a smaller number and vise versa. For this comparator 12A is equal 12B but it's up to you.

Ad.2.

@SortComparator(HouseComparator.class)
List<House> findByHouseNumber(Pageable pageable);
like image 112
xenteros Avatar answered Oct 11 '22 05:10

xenteros


I think you could try the Spring Data JpaSort class which allows function calls.

As stated in the documentation you will have something like :

@Query("select u from User u where u.lastname like ?1%")
  List<User> findByAndSort(String lastname, Sort sort);

repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)"));

You could also use it with a Pageable object.

like image 23
Stephane L Avatar answered Oct 11 '22 06:10

Stephane L