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
Related
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
Like said in the title I am trying to sort my data from sqlite database to ascending time. Here is what I have so far:
Cursor display = db.rawQuery("SELECT * FROM "+TableName + " ORDER BY Time ASC",null );
It displays data however it doesnt sort according to my Time with formade ##.## 24hr time. Hope someone can help.
Try "SELECT * FROM " + tableName + " ORDER BY time(Time)". PS: ASC is default ;)
You can use the strftime() function:
SELECT *
FROM my_table
ORDER BY strftime('%H:%M:%S',my_column)
Here I created a fiddle as example.
The raw query should be something like:
"SELECT * FROM " + TableName + " ORDER BY strftime('%H:%M:%S'," + my_column + ")"
NOTE: strftime() function is the more general function that you can use for manipulate date. But, for this specific case you can also use time(). Indeed, as the document that I linked says:
time(...) is equivalent to strftime('%H:%M:%S', ...)
I am currently implementing a search feature in an appliction to take a user input and query the database for similar results. I have created the following database query:
String proQuery = "SELECT * FROM " + DATABASE_TABLE + " WHERE "
+ KEY_NAME + " LIKE '%" + keyword +"%'";
Obviously this query has a number of limitations due to a very generic sql statement. For example, if I start typing something in the middle of the word, it will show up first in the list if it has a lower row number in the database.
Are there libraries that help make a more intelligent search feature than this very generic sql statement? I am not sure what keywords could describe this functionality what I'm looking for, is there some field of "search algorithms" for android?
Maybe UNION is what you're looking for:
SELECT * FROM (
SELECT * FROM table_name WHERE keyname LIKE 'keyword%' ORDER BY keyname
) alias_t1
UNION ALL
SELECT * FROM (
SELECT * FROM table_name WHERE keyname LIKE '%keyword%' AND keyname NOT LIKE 'keyword%' ORDER BY keyname
) alias_t2;
In android, SQLiteDatabase has a update function
update(String table, ContentValues values, String whereClause, String[] whereArgs)
new values in put in values
If I want to update a column A by adding one to it, how should I prepare the ContentValues values variable? I don't think the following would work.
cv.put("A", "A" + 1);
I can sure run execSQL with raw sql, but it does not return num of row updated
If you'd execute a raw query, something like this should work to increment the current value in the column:
UPDATE table_name SET column_a = column_a + 1 WHERE _id = 1
(where 1 is just an example to illustrate how to apply it to a specific row)
The same probably wouldn't work with ContentValues, since (as the name indicates) it takes the values to set the column to. That means it needs to have been evaluated before building the ContentValues, whereas with a raw query the value isn't evaluated until the query actually runs on the database.
You can of course retrieve the current value first and then increment that accordingly when issuing an update; that requires a select query first. Quite commonly though, you're working with objects in Java, where the column value for a row is bound up to a member field of the object. If you've got a setup like that, then you probably already have the current value at the moment you want to run an update query.
As such, it would just look somewhat like:
SomeObject object = ...;
cv.put("column_a", object.getSomeValue() + 1);
(where I'm assuming object.getSomeValue() will return an int)
// edit: here's some more examples for the raw query approach:
SQLite - increase value by a certain number
// edit2: You've edited your original question and added:
I can sure run execSQL with raw sql, but it does not return num of
row updated
If knowing how many rows the query changed is a must, then you can potentially leverage the changes() function. It still means you're going to have to run a second query though.
SELECT changes() FROM table_name
The docs say:
The changes() function returns the number of database rows that were
changed or inserted or deleted by the most recently completed INSERT,
DELETE, or UPDATE statement, exclusive of statements in lower-level
triggers. The changes() SQL function is a wrapper around the
sqlite3_changes() C/C++ function and hence follows the same rules for
counting changes.
Alternatively, you could look into the rawQuery() method that takes an SQL statement and returns the result as a Cursor. Not sure if it that even works for an update query, or whether the result would be anything sensible, but if you're really lucky, you may find that Cursor.getCount() gives you the number of affected rows.
To expand upon #MH's solution, there actually is a way to do a raw update AND get back the number of rows updated (because I'm doing the same thing in one of my projects). You have to use a compiled SQLiteStatement and then call the method executeUpdateDelete(). From the documentation:
public int executeUpdateDelete ()
Execute this SQL statement, if the the number of rows affected by execution of this SQL statement is of any importance to the caller - for example, UPDATE / DELETE SQL statements.
Returns
the number of rows affected by this SQL statement execution.
See the following sample code where I add a new column to my table and then update each column similarly to how you were asking:
db.beginTransaction();
try {
db.execSQL("ALTER TABLE " + TABLE_NAME + " ADD COLUMN "
+ COLUMN_NAME_LOCALTIME + " INTEGER");
String stmtString = "UPDATE " + TABLE_NAME + " SET "
+ COLUMN_NAME_LOCALTIME + "="
+ COLUMN_NAME_TIME + "+ (" + tzOffset + ")";
SQLiteStatement sqlStmt = db.compileStatement(stmtString);
int rows = sqlStmt.executeUpdateDelete();
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
I'm using a transaction here because in case I add the new column but CANNOT update the values, I want everything to rollback so I can attempt something else.
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