Room user configurable order by queries

As tyczj already suggested you can us a RawQuery. In addition, the SimpleSQLiteQuery can also be moved into the DAO so there are no SQL statements outside of the DAO.

A DAO can also be defined via an abstract class. This allows you to add a method which executes the SimpleSQLiteQuery.

Example:

@DAO
public abstract class UserDao {

    @RawQuery
    public abstract List<User> getUsersViaRawQuery(SupportSQLiteQuery query);

    public List<User> getUsersOrderBy(String column) {
        String statement = "SELECT * FROM user ORDER BY " + column + " ASC";
        SupportSQLiteQuery query = new SimpleSQLiteQuery(statement, new Object[]{});
        return getUsersViaRawQuery(query);
    }

}

The column parameter could also be replaced by an enum, which only allows specific values.

Example:

private static String createOrderByString(Order order) {
    switch (order) {
        case NAME:
            return "ORDER BY first_name ASC, last_name ASC";
        case AGE:
            return "ORDER BY age DESC";
        default:
            return "";
    }
}

In Room 1.1 there is now a RawQuery that can be used that solves this issue

 @Dao
 interface RawDao {
     @RawQuery
     User getUserViaQuery(SupportSQLiteQuery query);
 }
 SimpleSQLiteQuery query = new SimpleSQLiteQuery("SELECT * FROM User WHERE id = ? LIMIT 1",
         new Object[]{userId});
 User user2 = rawDao.getUserViaQuery(query);

https://developer.android.com/reference/android/arch/persistence/room/RawQuery


I'm facing the same problem right now. The thing that can be done is to use CASE:

SELECT * FROM Table
ORDER BY 
CASE WHEN :parameter = 1 THEN Column END ASC,
CASE WHEN :parameter = 2 THEN Column2 END DESC

But I'm assuming you are using a ViewModel as well, so you will probably have to reinitialise it every time. I think this way is a little bit better than writing 15 queries, maybe not as compact though.

This answer also has a nice example, but the logic is reversed I believe.