Android Room Advanced Query with list and multiple conditions - android

i have a query like this
#Query("SELECT * FROM table WHERE type IN(:types) AND selection = 0 ORDER BY timestamp DESC")
my problem is that i have one type in my type list lets say it's type=4 for which i want selection = 1.
Is it possible to get the results in one query and how should the query look like?

Related

Room database - remove colon from query

I am trying to sort my data by ascending and descending order using room database. So I need to pass those parameter to the DAO.
This is my code:
#Query("SELECT * FROM DEVICES_TABLE ORDER BY :sortQuery")
fun sortDatabase(sortQuery: String): Flow<List<DeviceData>>
But when I pass title DESC as sortquery (title is column name), the query becomes:
SELECT *
FROM DEVICES_TABLE
ORDER BY 'title ASC'
I need to remove those single quotes from query for achieving the results. I need to sort with title, price, type etc. both ascending and descending. How can I do that?

SQLite query for matching one column with multiple values

I am developing android app using RoomDB.
In a table there is a column called category
Assuming the category has the values from A,B,C....Z
So i have 24 category
For filtering category A, My query will be where category=:A (ONE FILTER)
for filtering A and B , Then it will be where category=:A or category=:B(TWO FILTER)
My filtering column can be random it may be one,two or three and so on...
Is there any query to filter these type of case.
I tried REGEXP but roomDB not accepting that
Waiting for good solution
Thanks in advance!
You can use in clause like this
select * from emp where dept in ('IT','HR','FIN');
If you have a pattern to search you can use like clause
select * from emp where name like ('%I%');
This will give you all employees having I in their name.

How to implement a string array in a query?

I want to get data from my room db with the following query:
#Query("SELECT address.address_id, first_name, last_name, street, postal_code, city," +
"(SELECT employee.employee_id FROM employee WHERE employee.address_id = address.address_id) AS employee_id, " +
"(SELECT project.project_id FROM project WHERE project.address_id = address.address_id) AS project_id " +
"FROM address WHERE last_name IN (:pattern) OR first_name IN (:pattern) ORDER BY last_name ASC, first_name ASC")
LiveData<List<AddressBookAddress>> loadAddressBookWithFilter(String... pattern);
As you can see my parameter accepts an array with one or more search strings.
Let's take for example "max" and "muster"
Now I want to get all records which contain the first names "max" or "muster" or the last names "max" or "muster". But currently, I'm not receiving any data at all.
The docs show it as quite straightforward thing. Look at Room Query docs. There you can see this example:
As an extension over SQLite bind arguments, Room supports binding a list of parameters to the query. At runtime, Room will build the correct query to have matching number of bind arguments depending on the number of items in the method parameter.
#Query("SELECT * FROM user WHERE uid IN(:userIds)")
public abstract List findByIds(int[] userIds);
For the example above, if the userIds is an array of 3 elements, Room will run the query as: SELECT * FROM user WHERE uid IN(?, ?, ?) and bind each item in the userIds array into the statement.
So, change signature from "String..." to "String[]" to clearly state an array presence.
There is no document for kotlin on this page but you can use this code for the same.
#Query("SELECT * FROM employee WHERE id IN(:idList)")
fun getAllSelectedEmployee(idList:Array<String?>): List<Model>

Dynamically build query in Room

Question
Is it possible to dynamically build the filtering for a query?
The problem
I have a big list, addresses. The user can filter it with typing text in a SearchView. If the user put any space in the text it will be divided and the two part of the text will be searched separately. I have to build the SQL dynamically because I didn't know how many space characters will be. Is there any way to handle this in Room whit simple #Query or I have to use #RawQuery for this?
Example SQL for this:
SELECT * FROM ADDRESS WHERE (CITY LIKE '%abc%' OR STREET LIKE '%abc%') AND (CITY LIKE '%abc%' OR STREET LIKE '%def%') AND (....)
I think what you should do is use RawQuery.
Since your query is complicated and you are not sure how long it is, you should probably construct it in runtime and execute it as well.
Room check the validity of the #Query in compile time so I think you'll have a hard time to implement it that way.
This example is taken from the documentation:
#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);
You can pass those words in an array
#Query("SELECT * FROM ADDRESS WHERE CITY LIKE(:keywords)") //customize your query here
List addresses(String[] keywords);

Sort by order in Query

I am using Room as ORM. I want to get array of some objects from it with a specific order. My code looks like this:
#Query("SELECT * FROM `group` WHERE id IN (:ids) ORDER BY id in (:ids)")
But "order by" not works. I don't want just to sort it by field "id". I want to sort it by id that correlate with array "ids". I mean:
I have array of Integer ids = arrayOf(16,12,18,3) and i use it in query above. And on the output i want to have array of some object(say group). The output array will looks like this
ListOf(Group(id:16, name: "someName"),
Group(id: 12, name: "someAnotherName",
Group(id: 18, name: "name"),
Group(id: 3, name: "another"))
So you where quite close. Try using
#Query("SELECT * FROM `group` WHERE id IN (:ids) ORDER BY id")
That should work for you. Im not sure on the group
You using wrong way, ORDER BY id in (:ids) is incorrect
it should be
#Query("SELECT * FROM `group` WHERE id IN (:ids) ORDER BY id")
To retrieve data from database in the order you want is impossible, as the database don't know about current indexes in the array for ids. Actually it's possible, but you have to provide this information in a query or store it beforehand in a table.
What you actually want, is to get corresponding group information by some ids, so
retrieve group data without ordering
#Query("SELECT * FROM group WHERE id IN (:ids)")
fun getGroupsById(): List<Group>`
store the result into a map
val idToGroups = mapOf<Long, Group>()
for (group in getGroupsById()) {
idToGroups[group.id] = group
}
then while iterating over initial ids array, get corresponding groups by id
for (id in ids) {
// here group is related to each position in the array
group = idToGroups[id]
println("Id: ${id}, Name: ${group.name}")
}

Categories

Resources