Is it possible to sort the results alphabetically and then numerically when pulling data from the Contacts table?
Code snippet:
cursorLoader.setSortOrder(
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC, " +
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " ASC, " +
ContactsContract.CommonDataKinds.Phone.IS_SUPER_PRIMARY + " DESC, " +
ContactsContract.CommonDataKinds.Phone.IS_PRIMARY + " DESC");
This results in numerical values appearing before alphabetical values
If you mean that the display name can contain numbers and names and you want the numbers to appear last e.g.
And you want Fred to appear before 01 23456 7890 but say for Alan to appear before Fred then one way would be to introduce a means of detecting whether or not the value is a number. This can be accomplished by trying to convert the value to a number (integer in this example) using a CAST.
So instead of :-
SELECT * FROM phonedata ORDER BY display_name ASC, contact_id ASC, is_super_primary DESC, is_primary DESC
which results in :-
You could use something along the lines of :-
SELECT
CAST(replace(display_name,' ','') AS INTEGER) AS converted,
*
FROM phonedata
ORDER BY CAST(replace(display_name,' ','') AS INTEGER) ASC,
display_name ASC,
contact_id ASC,
is_super_primary DESC,
is_primary DESC
This would produce :-
Notes
The converted column has been included for illustration.
That is it shows how an alphabetic value will result in 0 from the CAST, thus making it top order for the sort, whilst a numeric value (except 0)
You may need to tailor the above but basically the principle applies
Related
I have the following table:
String sqlStatement = "CREATE TABLE " + CallsEntry.TABLE_NAME + "(";
sqlStatement += CallsEntry.FIELD_CALL_ID + " INT PRIMARY KEY DESC,";
sqlStatement += CallsEntry.FIELD_CALLER_PHONE + " TEXT,";
sqlStatement += CallsEntry.FIELD_INSERTION_DATE_MILLIS + " INT); COMMIT;";
db.execSQL(sqlStatement);
Please note that the primary key is descending.
Then I expect from my experience with SQL server that the following query will yield the records in an descending order:
SELECT * FROM tblCalls;
However, this is not the case. I'm getting the records in ascending order. I have to use this:
SELECT * FROM tblCalls ORDER BY CallId DESC;
Why is that? Can I do something differently and get the records in descending order?
There is no such thing as default key order in SQLite.
Depends on documentation:
If a SELECT statement that returns more than one row does not have an
ORDER BY clause, the order in which the rows are returned is
undefined. Or, if a SELECT statement does have an ORDER BY clause,
then the list of expressions attached to the ORDER BY determine the
order in which rows are returned to the user.
So default order is underfined without ORDER BY clause.
Does this produce the right order?
SELECT CallId FROM tblCalls
I have a data table written in an SQLite Database and I want to retrieve it based on the ROWID, for example row 3? I tried SELECT * FROM TABLE WHERE ROWID=3; but that didn't work.
EDIT: What I am hoping to achieve is retrieve just the 3rd row without using the LIMIT function. I thought I could achieve this using the ROWID, but I see I can't do that.
SELECT * FROM TABLE_NAME LIMIT 1 OFFSET 2
LIMIT
It specifies a limited number of rows in the result set to be returned based on number_rows.
OFFSET
Optional. The first row returned by LIMIT will be determined by offset_value.
Try using a cursor for this:
Cursor cursor = db.rawQuery("select * from " + YOUR_TABLE + " where ROWID = 3", null)
String info = cursor.getString(cursor.getColumnIndex(YOUR_COLUMN_NAME));
//repeat this for all your different columns (different strings or just append to info depending on what you want achieve
cursor.close() //remember to close the cursor
I have a query that I am using to make a leader board for an android application that will grab data out of an Sql database and order by score. Although with this I want to add the rankID which is a primary field as a positional value in this leader board. How would I go about doing this so I have it ordered by score and have positions in descending order?
String selectQuery = "SELECT rankID, firstName, lastName, score " +
"FROM leader " +
"ORDER BY score DESC " +
"LIMIT 10";
In mysql
SELECT #rankID:= #rankID +1, firstname, lastname, score
FROM leader,
(SELECT #rankID:= 0) r
ORDER BY score DESC
LIMIT 0,10;
I would probably just loop it myself in my code and use that as my counter instead of doing it this way though.
Here you're misplacing the order by columns. If you require ordering by KEYWORD_TEXT then by BID_AMOUNT and CITY (if yes then)
Change order by as:
ORDER BY KEYWORD_TEXT, BID_AMOUNT CITY
I have a database saved in my Android application and want to retrieve the last 10 messages inserted into the DB.
When I use:
Select * from tblmessage DESC limit 10;
it gives me the 10 messages but from the TOP. But I want the LAST 10 messages. Is it possible?
Suppose the whole table data is -
1,2,3,4,5....30
I wrote query select * from tblmessage where timestamp desc limit 10
It shows 30,29,28...21
But I want the sequence as - 21,22,23...30
Change the DESC to ASC and you will get the records that you want, but if you need them ordered, then you will need to reverse the order that they come in. You can either do that in your own code or simply extend your query like so:
select * from (
select *
from tblmessage
order by sortfield ASC
limit 10
) order by sortfield DESC;
You really should always specify an order by clause, not just ASC or DESC.
on large databases, the ORDER BY DESC statement really might slow down the system, e.g. raspberry pi. A nice approach to avoid ORDER BY is the OFFSET command. And you even keep the stored order:
SELECT * FROM mytable LIMIT 10 OFFSET (SELECT COUNT(*) FROM mytable)-10;
see: http://www.sqlite.org/lang_select.html
check out your performance with:
.timer ON
Slightly improved answer:
select * from (select * from tblmessage order by sortfield DESC limit 10) order by sortfield ASC;
Michael Dillon had the right idea in his answer, but the example gives the first few rows, inverted order:
select * ... (select * ... ASC limit 10) ... DESC
He wanted the last, it should be:
select * ... (select * ... DESC limit 10) ... ASC
Try this,
SQLiteDatabase database = getReadableDatabase();
Cursor c=database.rawQuery("sql Query", null);
if(c.moveToFirst) {
int curSize=c.getCount() // return no of rows
if(curSize>10) {
int lastTenValue=curSize -10;
for(int i=0;i<lastTenValue;i++){
c.moveToNext();
}
} else {
c.moveToFirst();
}
}
Then retrieve the last 10 data.
If your table contains a column with primary key autoincrement (some "row_id" for example) then you just need single select with DESC order by this column
Raw request looks like
select * from table_name order by row_id DESC limit 10
Android implementation is
private Cursor queryLastEvents() {
return getDatabase().query("table_name", null, null, null, null, null, "row_id DESC", "10");
}
"SELECT * FROM( SELECT * FROM " + tablename + whereClause + " ORDER BY timestamp DESC LIMIT 10) ORDER BY timestamp ASC";
In your query, the DESC is interpreted as a table alias.
As mentioned by ρяσѕρєя K, to be able to specify a sorting direction, you need to sort in the first place with an ORDER BY clause.
The column to be sorted should be a timestamp, if you have one, or an autoincrementing column like the table's primary key.
select * from
(select * from table_name order by yourfield ASC limit 10)
order by yourfield DESC;
You cannot have better solutions than this.
cursor.moveToLast();
while (cursor.moveToPrevious()){
//do something
}
with same query: select * from tblmessage where timestamp desc limit 10
I'm working with the Android SQLite db, and I have a table with messages in it. Each message has a ContactId. I need to get a list of the newest message associated with each ContactId.
My query looks like this so far:
SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC
However when I run the query I get this exception:
near "ContactId": syntax error: , while compiling: SELECT * FROM messages GROUP_BY ContactId HAVING ( COUNT(ContactId) = 1 ) ORDER_BY MessageTime DESC
Here's the table definition in case it helps:
create table messages (_id integer primary key autoincrement, ContactId text not null, ContactName text not null, ContactNumber text not null, isFrom int not null, Message text not null, MessageTime int not null);
NOTE: My answer below does not appear to be working as of SQLite 3.7.5, I suggest using the "JOIN" query suggested by Larry.
You are close. What you need to do is sort all the records first, using a subquery table, and then group them. The values that are returned in the result set will be from the last row in each group. So you actually want newer messages to appear at the bottom if you are trying to get the newset message. The "GROUP BY" already ensures you get one row per ContactId.
SELECT * FROM (SELECT * FROM messages ORDER BY MessageTime) GROUP BY ContactId
The HAVING clause is not needed. I haven't used it before but according to the docs the HAVING clause will discard whole groups that don't match, but it doesn't sound like you want any groups discarded, you want results from every ContactId.
Also note there is no underscore in "ORDER BY" or "GROUP BY".
Here are two ways to do it.
This query builds a list of the most recent times for each user, then JOINs that back to the message table to get the message information:
SELECT M1.* FROM messages M1 JOIN
(SELECT ContactId, MAX(MessageTime) AS MessageTime FROM messages GROUP BY ContactId) M2
ON M1.ContactID = M2.ContactID AND M1.MessageTime = M2.MessageTime;
This query does something slightly different. It looks at each message and asks if there exists any later message for the same contact. If not, the row must be the most recent one:
SELECT M1.* FROM messages M1
WHERE NOT EXISTS (SELECT * FROM M2
WHERE M2.ContactID = M1.ContactID AND M2.MessageTime > M1.MessageTime)