I need to retrieve last 25 rows from a table using ContentProvider. I have searched and came up with a solution which works fine on simple SQL Database.
SELECT * FROM( SELECT * FROM [Customers] ORDER BY CustomerID DESC limit 25)ORDER BY CustomerID ASC;
But as i said , m using ContentProvider, and in my onCreateLoader the procedure is like this :
CursorLoader(getActivity(), uri, projection, selection, null, sortOrder);
in which the bold portion of the above query i.e. FROM can only be a Uri.
And if i use
( SELECT * FROM [Customers] ORDER BY CustomerID DESC limit 25) as a Uri then Exception says that is not a valid Uri.
Is there any other way to achieve my objective or any modification in this query. Thanx.
Tell the content provider to return rows sorted by CustomerID DESC.
Once you have that cursor, just take the first 25 rows out of it, and sort them again, manually. (In this case, just reverse the order of the rows.)
If you still need to have the data in a cursor afterwards, store the values in your own MatrixCursor.
Related
Since the db does not have create date and some ordering field (but in my observation the last row is the latest record),
so how can i get the five last record in some condition e.g.
five record that their schoolid == 1?
Thanks
public Cursor select()
{
String orderBy = FIELD_pubKey+" DESC";
Cursor cursor = iReadDatabase.query(TABLE_NAME, null, null, null, null, null, orderBy);
cursor.moveToFirst();
return cursor;
}
There's no such thing as a last record or a first or a 42nd.
Which records appears last in the result of a query is dependent on the query plan, or an Explicit order by if you add one.
Select * From Table Where ...
The rows will be returned in whatever order the engine considers suitable at the time.
If you need them in specific order, then add an order by clause to the query, anything else is asking for it.
Something like
Select * From Table Order by SomeColumn desc limit 5
will do what you require.
Now what column you need to order by I've no idea, but you need one that will do the job, assuming automatic primary key, but note it is possible to mess with that.
I have a SQLite table (with more than 100000 rows) that I want its rows streamed.
I do:
Cursor cursor = db.rawQuery("SELECT _id FROM hugetable", new String[] {});
The problem is that just getting the first row as:
cursor.moveToFirst()
seems to load the whole table, being quite slow.
Is there a way to stream a query without having wait to load all the rows when fetching the first row?
(like I can do with the plain C SQLite API outside Android)
The Android Cursor is designed to load all data for caching.
To work arouns this, you have to manually query the data in steps:
SELECT _id
FROM hugetable
ORDER BY _id
LIMIT 100;
SELECT _id
FROM hugetable
WHERE _id > last_id_from_previous_query
ORDER BY _id
LIMIT 100;
I have a cursor with multiple records, and each record has a unique "_id" column plus other columns.
I want to know if it is possible to retrieve a particular record with a specified _id, widout iterating over all d records?
no, Cursor is a resultset, you can perform join operation on cursor, but can't access records by values.
Unless I misunderstand your question, you could also request a new cursor for the particular record you want.
example:
rawQuery("SELECT * FROM simpletable WHERE _id="+YOUR_ID_VALUE,null);
I am looking to perform the following query (in pseudo-code) on Android:
SELECT C.ID, C.NAME, CASE ISNULL(G.GROUPID,0) = 0 THEN 0 ELSE 1 END INGROUP
FROM CONTACTS C
LEFT JOIN GROUPMEMBERSHIP G ON G.CONTACTID = C.ID AND G.GROUPID = ?
I am looking to select the ID and Name of ALL contacts in the system address book, via the default Contacts ContentProvider, along with a
0/1 field indicating whether the contact is a member of group ? .
I could of course get all contacts easily enough, then loop through and query the membership separately easy enough in my Adapter class, but I'd imagine performing the two queries as one outer joined query would yield much better performance.
Can I do this with the standard high-level string-projection and ContentResolver.query() method? Or would this kind of query require digging into more direct SQL execution?
Edit: Okay, so this doesn't actually solve the question asked, because eidylon is tied to an existing ContentProvider as mentioned in their question. However, this does cover how you do a JOIN if you own the ContentProvider source and API. So I'll leave it for those who want to know how to handle that case.
This is easy! But unintuitive... :)
query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
Okay, so what is URI? Typically, you have one URI per table.
content://com.example.coolapp.contacts serves data out of your CONTACTS table.
content://com.example.coolapp.groupmembers serves data out of your GROUPMEMBERSHIP table.
But URI is really just a string. Use it however you like. Make a block of code in your ContentProvider that responds to content://com.example.coolapp.contacts_in_group. Within that block of code in the ContentProvider, you can get raw access to your SQLite DB, unfettered by the limited query() data model. Feel free to use it!
Define your selection fields however you like. They don't have to map to table column names -- map them how you need to, in order to get your parameters in.
Define your projection how you need -- It may contain columns from both tables after the join.
Bing, you're done. Google does this same model internally in their own code -- Go look at the Contacts provider API -- you see "bla.RawContact" and "bla.Contact" and etc as content URIs. Each serves data out of the same table in the DB -- the different URIs just provide different views of that same table!
Nope, you can't do that kind of queries with the ContentResolver.query() method.
You will need to write something like this:
SQLiteDatabase db = YourActivity.getDbHelper().getReadableDatabase();
String query = yourLongQuery;
Cursor c = db.rawQuery(query, null);
YourActivity.startManagingCursor(c);
c.setNotificationUri(YourActivity.getContentResolver(), YourContentProvider.CONTENT_URI);
You can't do that because ContentResolver has only one query method:
query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
there's no parameter for tables or FROM clauses.
I get records from the system by quering a ContentResolver. I maintain the order of the items in the database. So I want to display the items in the order taken from my database.
How do I merge these two informations?
EDIT 1
I am looking after an alternative way now. As what I ideally want is:
get order of contacts by a custom order held in my database (this involves joining CR with my DB cursor, and doing an order by, later seams it's not possible with CursorJoiner)
but there is more, if the join is not unique I want to sort by contact's name as last measure
which is impossible using Cursor and Joiners, because of the missing feature of order bys, also I need to return a Cursor, as I will be using the in an ExpandableList
Also this translated to TSQL it would look like
select * from contactsdata
left join category on contactsdata.catid=category.id
order by category.pos asc, contact.display_name asc
So I am looking now after an alternative.
I have in mind to load in a temporary DB table all data from CR, then do the query on the temporary table where I can join tables and do order bys? How does this sound to you?
Take a look at CursorJoiner.
If that doesn't work, you can roll your own equivalent with a fair amount of pain, whiskey, or both.