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);
Related
I'm comparing two dates in android sqlite database
I stored dates in the format
YYYY-MM-DD
Cursor cursor=db.rawQuery("SELECT * FROM "+tableName+" WHERE SALESDATE BETWEEN '2020-1-01' AND '2020-2-01';",null);
It gives result with dates of month 10, 11 and 12 along with the dates between above specified dates.
I would like to know if it is a bug or is there any mistake in my code.
The problem here is that your date literals are in a non standard (and likely incorrect) format. Appreciate that the following inequality holds true:
'2020-10-01' > '2020-1-01' AND '2020-10-01' < '2020-2-01'
This is true because the text 10 is lexicographically larger than just 1, but also less than 2. To avoid this problem, use proper date literals:
String sql = "SELECT * FROM " + tableName + " WHERE SALESDATE BETWEEN '2020-01-01' AND '2020-02-01';"
Cursor cursor = db.rawQuery(sql, null);
Note that SQLite does not actually have a formal date type. Thus, it is very important to always store your dates in SQLite using a proper ISO format.
You should store your Date as long value in database. Simple new Date().getTime() gives you this value and new Date(long value) returns it back. So you can make such queries easy.
But what I can suggest is to:
Export your table to CSV,
Change the date values to a proper SQLite TimeString and
Re-import the CSV after deleting the original table.
Then, you can run a query like:
SELECT * FROM tableName WHERE SALESDATE BETWEEN '2020-01-01 00:00:00' AND '2020-02-01 23:59:59'
I am trying to pull last 31 days data from SQLLite db, using below SQL. I already searched google and tried various options, while all SQL works i am not getting results as expected. For example in below screenshot you will see i do have record on 18-Sep but sql doesn't return any results...I am not sure what i am missing here..
SELECT * FROM transactions WHERE TIMESTAMP > (SELECT DATETIME('now', '-30 day'))
Use between instead of Timestamp comparison directly -
SELECT * FROM transactions WHERE TIMESTAMP BETWEEN datetime('now', '-31 days') AND datetime('now', 'localtime')
This is because SQLlite stores dates in String format and doesn't have a standard DateTime format. So The direct comparison of String would fail. Hence using of the datetime function to compare dates with existing values helps.
You can also try as
SELECT * FROM TRANSACTIONS WHERE TIMESTAMP > datetime('now', '-30 days')
I want to get the latest 5 records in my table, so far i tried this but, it did not work out very well. So, what is the cleanest and efficient way to get last 5 records in the table ?
"select * from (select * from People order by Date DESC limit 5) order by Date ASC;"
Your query works just fine.
To make it efficient, ensure that there is an index on the Date column; then SQLite will just read the last five entries from the index and the table and does not need to scan the entire table.
If this table has an autoincrementing ID column, and if "latest" means the insertion order, then you can use that ID for sorting; this will be as efficient as your original query with an index on Date:
SELECT * FROM (SELECT * FROM People
ORDER BY _id DESC
LIMIT 5)
ORDER BY Date ASC
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
My app reads an XML file on the internet, takes note of the time and creates/writes an SQLite database. The next time data is required, if the time is >24hrs the database is updated (xml downloaded again).
The problem is that whenever I relaunch the app in AVD it has to re-download and so I notice that all the data in the database is written again (duplicated). So instead of 10 items, I have 20 (10+10 duplicates). If I relaunch again I get another 10 items duplicated.
I thought about how I could prevent the duplication of the database (or delete the old entries), so I decided to increment the database version every time the content is downloaded. I thought this would trigger the onUpgrade() method so the data would be cleared but nothing changes.
Now I am clueless. How should I go about this?
On your database create you'll want to use the UNIQUE constraint. You may not want the ON CONFLICT REPLACE that i use, but you should get the idea.
For Ex:
private static final String DATABASE_CREATE_NEWS= "create table news (_id integer primary key autoincrement, "title text not null, description text not null, date text not null, LastModified text not null, UNIQUE(title, date) ON CONFLICT REPLACE);";
Here is another solid thread that talks about it as well.
SQLite table constraint - unique on multiple columns
Here is some more info on the android sqlite: http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html
You should create an index on the columns that represent a unique identifier.
see this article on SQLite's website.
CREATE INDEX ix_tblexample ON TableName ( Column1, Column2, Column3 [, Column4, etc..])
Or (as per your comment) you can select the table into a cursor and check for each one.
String sql = "select * from " + tableName + "where column1 = " + param1 + "and column2 = " + param2;
Cursor cur = _db.rawQuery( sql, new String[0] );
if(cur.getCount() == 0)
{
//upload
}