I have an SQLite database with some to do lists. Each to do list, there is a column for tag.
Here is a sample layout of my SQLite database
Let’s say I want to select the to do lists with tags containing “Me” and “Mom” (ie “Buy groceries”, “Study” and ” Holiday trip”), how do I do this?
I have consider this, but I dont think it works.
public getToDoLists (String [] tags) { this.db = openHelper.getReadableDatabase(); String query = " SELECT * FROM " + TABLE_NAME + " WHERE " + COL2 + " ='" + tags + "'"; c = db.rawQuery(query, null); ....... ....... }
Advertisement
Answer
This is not a simple query.
You are passing the tags that you search for as a String array.
One option is to use a for
loop which will iterate all the tags of the array and for each tag run a query, but this is bad for performance.
The option that I suggest is to join all the tags separated with ,
in a string and pass it to a query which in turn will split it with a recursive CTE and run a SELECT...
statement with EXISTS...
to fetch the matching rows:
public Cursor getToDoLists(String[] tags) { String joinedTags = TextUtils.join(",", tags); String query = "WITH " + " list(tag) AS (SELECT ?), " + " cte(tag, value) AS ( " + " SELECT SUBSTR(tag, 1, INSTR(tag || ',', ',') - 1), " + " SUBSTR(tag, INSTR(tag || ',', ',') + 1) " + " FROM list " + " UNION ALL " + " SELECT SUBSTR(value, 1, INSTR(value || ',', ',') - 1), " + " SUBSTR(value, INSTR(value || ',', ',') + 1) " + " FROM cte " + " WHERE LENGTH(value) > 0 " + ") " + "SELECT t.* " + "FROM " + TABLE_NAME + " t " + "WHERE EXISTS ( " + " SELECT 1 FROM cte c " + " WHERE ',' || REPLACE(t.Tags, ', ', ',') || ',' LIKE '%,' || c.tag || ',%' " + ")"; SQLiteDatabase db = this.getReadableDatabase(); return db.rawQuery(query, new String[] {joinedTags}); }
I use REPLACE(t.Tags, ', ', ',')
in the sql statement because I see that the separator of the tags in the column Tags
is ', '
and not ','
.
If I’m mistaken then change REPLACE(t.Tags, ', ', ',')
with just t.Tags
.
The method getToDoLists()
must be placed inside your SQLiteOpenHelper
class and you can call it from your activity class like:
Cursor c = openHelper.getToDoLists(new String[] {"Me", "Mom"});
and it returns a Cursor
with the rows matching your criteria, which you can iterate.
To use TextUtils.join()
you will need this import:
import android.text.TextUtils;
See a demo of how this works in SQLite.