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
Related
Lets say there is a table of price submissions that consist of rowId, shopID, goodID, price, submission time. I'm trying to retrieve the oldest price submission in a given shop. My query looks like this:
Cursor c = database.rawQuery("SELECT * FROM price_submissions WHERE validshop = '-Kcq2pOeJA2_URuJLFKC' AND submissiondateandtime = (SELECT min(submissiondateandtime) FROM price_submissions)", null);
This query returns 0 results. Though if I replace part (SELECT min(submissiondateandtime) FROM price_submissions) with actual min (oldest) value, it does return a row.
Why doesn't the initial query work?
SELECT min(submissiondateandtime) FROM price_submissions returns the oldest price submission not in the given shop, as you write in the textual description, but in the whole table. You might have meant SELECT * FROM price_submissions AS outer WHERE validshop = '-Kcq2pOeJA2_URuJLFKC' AND submissiondateandtime = (SELECT min(submissiondateandtime) FROM price_submissions AS inner WHERE inner.validshop = outer.validshop)
First run SELECT min(submissiondateandtime) FROM price_submissions and store min value in one varaiable X then use it in parent query SELECT * FROM price_submissions WHERE validshop = '-Kcq2pOeJA2_URuJLFKC' AND submissiondateandtime=X
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 two identical tables (month1, month2) and I am trying to find all records from both tables where task1_done = 1. I want the last row in that set (i move cursor to last for this). I have played with inner outer natural joins but can't seem to get month2 values. Here is what I have:
String query = "SELECT m1.columnA, m1.columnB, m1.columnC, m1.columnD, m1.columnE, m1.columnF FROM month1 m1, month2 m2 WHERE m1.task1_done = 1 OR m2.task1_done = 1";
Any help would be great!
I think you want a union all for this query:
select m.*
from (select *
from months1
union all
select *
from months2
) m
where task1_done = 1;
Note: I have used * as a convenience because you said the two tables have the same structure. You should actually list the columns that you want from the two tables.
In general, having two tables with the same layout is a sign of a bad database design. It is usually better to have a bigger table, with another column identifying "month1" or "month2".
EDIT:
SQL tables do not have a "last" value. If you have a an id or timestamp column that you can use for ordering, then you can do:
select m.*
from (select *
from months1
union all
select *
from months2
) m
where task1_done = 1
order by id desc
limit 1;
Are these tables related or have any references? if not you can have separate statement and do a union
i.e.
select top 1 column1, column2.. from month1 WHERE task1_done = 1 order by IdentityColumn Desc
union
select top 1 column1, column2.. from month2 WHERE task1_done = 1 order by IdentityColumn Desc
I want to delete all rows in table MYTABLE which are older than x days. Column SAVE_DATE Long is the time when the row was inserted in table.
I tried this but apparently it deletes all my rows:
long daysInMiliSec = new Date().getTime() - X
* (24L * 60L * 60L * 1000L);
return db.delete(MYTABLE , SAVE_DATE
" <= ?", new String[] { "" + daysInMiliSec }
What is wrong?
Below query will delete data older than 2 days:
String sql = "DELETE FROM myTable WHERE Save_Date <= date('now','-2 day')";
db.execSQL(sql);
Since it's the first hit on google some more explanation for beginners:
You do not need the time/date functions from the main program you use to access the sqlite DB but use the sqlite date functions directly.
You create the table with the row entry for the age with for example:
CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, text TEXT, age INTEGER)
You write to it with
INSERT INTO test (text, age) VALUES ("bla", datetime('now'))
Here I used 'datetime' because this also will let you later search for hours/minutes/seconds. If you don't need that 'date('now')' is enough.
Here is an explanation for the date function: https://www.sqlite.org/lang_datefunc.html
To select everything older than for example 5 minutes:
SELECT * FROM test WHERE age <= datetime('now', '-5 minutes')
You can see more of those possibilities on the website above under the paragraph 'Modifiers'.
Delete data older than 2 days when the timestamp or date field is stored in milliseconds or an epoch integer.
DELETE FROM update_log WHERE timestamp <= strftime('%s', datetime('now', '-2 day'));
With the latest version of ORMLite for SQLite Android: http://ormlite.com/sqlite_java_android_orm.shtml, you may achieve this by using the following code:
String sql = "DELETE FROM graph WHERE time <= 1522405117";
dbHelper.getWritableDatabase().execSQL(sql);
I want to make a query such that the result will be shown in indistinct descending order.
For example, assume column ID has six rows. I need an query that shows me the list of IDs indistinct descending from 6 to 1.
EDIT: Based on the first post's text, the question is how do display query results in descending order. For instance, given the IDs
ID
--
1
2
3
4
5
6
Desired results:
ID
--
6
5
4
3
2
1
You need to add an ORDER BY ID DESC to your select statement.
ORDER BY
Use following statement....
select * from YOUR_TABLE_NAME ORDER BY ID DESC;
You can write like this:
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME+"
WHERE "+STATUS+" = "+"'0'" + " ORDER BY id DESC LIMIT 10", null);
return cursor ;
/* In the most simple and basic way, you can write it as */
SELECT ID
FROM your_table_name
ORDER BY ID DESC;
/* This should work fine with your problem and should give you your desired output */