I am using rawquery() for perform inner join, but this is not giving me any error and does not working, if i use this query directly into sqlite browser than this is working but in application this query does not work, following is my code, sorry for bad English communication
public void deleteFifo() {
final String MY_QUERY1 = "Delete from Items where res_id in (select _id from Favourite where _id not in (select _id from Favourite order by date desc limit 50))";
final String MY_QUERY2 = "Delete from Favourite where _id not in (select _id from Favourite order by date desc limit 50)";
db.rawQuery(MY_QUERY1, null);
db.rawQuery(MY_QUERY2, null);
}
Try:
db.delete(TableName, whereCondition, null);
i.e. in your case
db.delete("Items", "res_id in (select _id from Favourite where
_id not in (select _id from Favourite order by date desc limit 50))", null);
and
db.delete("Favourite ","_id not in (select _id from Favourite
order by date desc limit 50)");
Hope it helps !!
Related
I'm using SQLite in Android (minSdkVersion: 15). I have table like this:
I'm trying to get list of last inserted rows with trainingId as a parameter. For example, I'd like to get list of last inserted rows with trainingId = 1 and the result should be:
13---5---1
14---5---1
15---5---1
or if trainingId = 2, then:
10---4---2
11---4---2
12---4---2
I tried something like this:
SELECT * FROM table_name JOIN (SELECT MAX(trainingDoneId) AS trainingDoneId FROM table_name GROUP BY treningId) USING (trainingDoneId)
and
SELECT * FROM table_name WHERE trainingDoneId IN (SELECT MAX(trainingDoneId) FROM table_name GROUP BY 1)
but in both cases I get this error:
android.database.sqlite.SQLiteException: aggregate functions are not allowed in the GROUP BY clause (code 1)
Any suggestions?
Please fire below query it will help you,
SELECT * FROM table_name where trainingId = 1 AND trainingDoneId in (select max(trainingDoneId) from table_name where trainingId = 1)
SELECT id, MAX(trainingDoneId), trainingId FROM table_name WHERE trainingId = 1 ORDERBY id
Try with this solution
I'm developing an Android app based on SqlLiteDataBase.
When I query the db using the query method, I want to order by a date column in ascending order.
It seems the ORDERBY is not working.
Cursor cursor = db.query("myTable", // The table to query
dbTools.tableColumns, // The columns to return
whereClause, // The columns for the WHERE clause
null, // The values for the WHERE clause
null, // don't group the rows
null, // don't filter by row groups
"dateText" + " ASC" // The sort order
);
The cursor mquery field during debug shows the following:
SQLiteQuery: SELECT dateText, <some other columns here> FROM myTable WHERE dateText >= '2015-10-01 00:00:00' AND dateText <= '2015-10-31 23:59:59' ORDER BY dateText DESC
(I removed irrelevant columns for your convenience)
After running the query, I want to check whether I have any entry, so I call:
if (!cursor.moveToFirst())
Then I do some logic and whenever I want to move to next row on cursor I run:
if (!cursor.moveToNext())
dateText column is defined as DATETIME:
String query = "CREATE TABLE myTable (id INTEGER PRIMARY KEY AUTOINCREMENT, dateText DATETIME, <other columns here>)";
Can you please advise why the sorting is not working? The rows are not sorted when iterating over the rows on the cursor.
Example:
if I have rows for 1st, 2nd and 10th of November 2015, the sorting by ASC will give this sorting: 10->1->2
Sorting by DESC gives: 2->10->1
here what i propose to you to try :
SQLiteQuery: SELECT dateText, FROM myTable WHERE dateText >= '2015-10-01 00:00:00' AND dateText <= '2015-10-31 23:59:59' ORDER BY date(dateText) DESC
and Be-careful for :
Dest ==> Descendant
ASC ==> Ascendant
Good luck !!
I want to order by a date column in ascending order
But your code show
ORDER BY dateText DESC
Change it ASC is default option, so you can remove it
ORDER BY dateText ASC
I am using INNER JOIN on two tables,table1 and table2, from my SQLite Database.
How do I access the results(columns of both tables) from the cursor? The two tables have 2 columns with same name.
String query = SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
Cursor c = newDB.rawQuery(query, null);
You can specify column names instead of using '*'.
String query = SELECT table1.id AS ID,table2.column2 AS c2,...... FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
and then access using column name ID,c2 etc .
while (cursor.moveToNext()) {
String c2 = cursor.getString(cursor.getColumnIndex("c2"));
int id = cursor.getInt(cursor.getColumnIndex("ID"));
..............
.............
}
Editing the broken link : Check rawQuery methid here http://www.vogella.com/tutorials/AndroidSQLite/article.html
and here http://www.codota.com/android/methods/android.database.sqlite.SQLiteDatabase/rawQuery for different examples
You can access the result as you would with any other query.
The only difference is that there is a chance to name conflicts, same column name on both tables. In order to solve those conflict you would need to use the table name as a prefix.
For example
Long id = c.getLong(c.getColumnIndex(tableName1 + "." + idColumnName));
If this approach doesn't work. You should write your query as follows:
String query = SELECT table1.id AS table1_id FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
Cursor c = newDB.rawQuery(query, null);
And another general note, it is better not to use "Select *..." it is preferred to write explicitly which column you would like to select.
Cursor c=databseobject.functionname() //where query is used
if(c.movetofirst()) {
do {
c.getString(columnindex);
} while(c.movetoNext());
}
I have used the following to do an inner join:
public Cursor innerJoin(Long tablebId) {
String query = SELECT * FROM table1 INNER JOIN table2 ON table1.id=table2.id WHERE name like '%c%';
return database.rawQuery(query, null);
}
You can Iterate your cursor as below:
Cursor cursor = innerJoin(tablebId);
String result = "";
int index_CONTENT = cursor.getColumnIndex(KEY_CONTENT);
cursor.moveToFirst();
do{
result = result + cursor.getString(index_CONTENT) + "\n";
}while(cursor.moveToNext());
Hope this works for you
If you know the column name then you can find it like below,
long id = cursor.getLong(cursor.getColumnIndex("_id"));
String title = cursor.getString(cursor.getColumnIndex("title"));
if you just want to see all the columns name of the returned cursor then you can use String[] getColumnNames() method to retrieve all the column names.
Hope this will give you some hint.
Please let me know how to delete n-rows in android sqlite database. I used this code:
String ALTER_TBL ="delete from " + MYDATABASE_TABLE +
"where"+KEY_ID+"in (select top 3"+ KEY_ID +"from"+ MYDATABASE_TABLE+"order by _id );";
sqLiteDatabase.execSQL(ALTER_TBL);
But it shows an error.
03-21 13:19:39.217: INFO/Database(1616): sqlite returned: error code = 1, msg = near "in": syntax error
03-21 13:19:39.226: ERROR/Database(1616): Failure 1 (near "in": syntax error) on 0x23fed8 when preparing 'delete from detail1where_id in (select top 3_idfromdetail1order by _id );'.
String ALTER_TBL ="delete from " + MYDATABASE_TABLE +
" where "+KEY_ID+" in (select "+ KEY_ID +" from "+ MYDATABASE_TABLE+" order by _id LIMIT 3);";
there is no "top 3" command in sqlite I know of, you have to add a limit
watch out for spaces when you add strings together : "delete from" + TABLE + "where" = "delete frommytablewhere"
This approach uses two steps to delete the first N rows.
Find the first N rows:
SELECT id_column FROM table_name ORDER BY id_column LIMIT 3
The result is a list of ids that represent the first N (here: 3) rows. The ORDER BY part is important since SQLite does not guarantee any order without that clause. Without ORDER BY the statement could delete 3 random rows.
Delete any row from the table that matches the list of ids:
DELETE FROM table_name WHERE id_column IN ( {Result of step 1} )
If the result from step 1 is empty nothing will happen, if there are less than N rows just these will be deleted.
It is important to note that the id_column has to be unique, otherwise more than the intended rows will be deleted. In case the column that is used for ordering is not unique the whole statement can be changed to DELETE FROM table_name WHERE unique_column IN (SELECT unique_column FROM table_name ORDER BY sort_column LIMIT 3). Hint: SQLite's ROWID is a good candidate for unique_column when deleting on tables (may not work when deleting on views - not sure here).
To delete the last N rows the sort order has to be reversed to descending (DESC):
DELETE FROM table_name WHERE unique_column IN (
SELECT unique_column FROM table_name ORDER BY sort_column DESC LIMIT 3
)
To delete the Nth to Mth row the LIMIT clause can be extended by an OFFSET. Example below would skip the first 2 rows and return / delete the next 3.
SELECT unique_column FROM table_name ORDER BY sort_column LIMIT 3 OFFSET 2
Setting the LIMIT to a negative value (e.g. LIMIT -1 OFFSET 2) would return all rows besides the first 2 resulting in deletion of everything but the first 2 rows - that could also be accomplished by turning the SELECT .. WHERE .. IN () into SELECT .. WHERE .. NOT IN ()
SQLite has an option to enable the ORDER BY x LIMIT n part directly in the DELETE statement without a sub-query. That option is not enabled on Android and can't be activated but this might be of interest to people using SQLite on other systems:
DELETE FROM table_name ORDER BY sort_column LIMIT 3
It seems that you've missed some spaces:
"where"+KEY_ID+"in..
must be:
"where "+KEY_ID+" in...
Furthermore you need to use the limit statement instead of top:
I'll do:
db.delete(MYDATABASE_TABLE, "KEY_ID > "+ value, null);
you can try this code
int id;
public void deleteRow(int id) {
myDataBase.delete(TABLE_NAME, KEY_ID + "=" + id, null);
}
String id;
public void deleteRow(String id) {
myDataBase.delete(TABLE_NAME, KEY_ID + "=\" " + id+"\"", null);
}
It is a bit long procedure but you can do it like this
first get the ids column of table from which which you want to delete certain values
public Cursor KEY_IDS() {
Cursor mCursor = db.rawQuery("SELECT KEYID " +
" FROM MYDATABASE_TABLE ;", null);
if (mCursor != null)
{
mCursor.moveToFirst();
}
return mCursor;
}
Collect it in an array list
ArrayList<String> first = new ArrayList<String>();
cursor1 = db.KEY_IDS();
cursor1.moveToFirst();
startManagingCursor(cursor1);
for (int i = 0; i < cursor1.getCount(); i++) {
reciv1 = cursor1.getString(cursor1
.getColumnIndex(DBManager.Player_Name));
second.add(reciv1);
}
and the fire delete query
for(int i = 0 ;i<second.size(); i++)
{
db.delete(MYDATABASE_TABLE KEYID +"=" + second.get(i) , null);
}
Delete first N (100) rows in sqlite database
Delete from table WHERE id IN
(SELECT id FROM table limit 100)
You can make use of the following mode: (in addition to the response provided by "zapl").
**DELETE FROM {Table-X} WHERE _ID NOT IN
(SELECT _ID FROM {Table-X} ORDER BY _ID DESC/ASC LIMIT (SELECT {Limit-Column} FROM {SpecificationTable}) );**
Where {Table-X} refers to the table you want to delete, _ID is the main unique-column
DESC/ASC - Based on whether you want to delete the top records or the last records, and finally in the "LIMIT" clause, we provide the "n" factor using another query, which calls in the {Limit-Column} from {SpecificationTable}: Which holds the value against which you want to delete them.
Hope this helps out someone.
Happy Coding.
I am banging my head over this for several hours, I tested many ways and I know where the proble is, but I just can't figure out how to fix it, I need an external point of view here.
That's my query code:
public Cursor getAllExpensesUser(int user){
String sql = "SELECT * FROM expense WHERE _id IN (SELECT id_expense FROM forwho WHERE id_user = "+ user +")";
return mDb.rawQuery(sql, null);
}
With this query it returns nothing.
When using the following query it returns my desired rows... obviously im using the id number directly.
`String sql = "SELECT * FROM expense WHERE _id IN (SELECT id_expense FROM forwho WHERE id_user = 2)";`
I have tried also with arguments:
public Cursor getAllExpensesUser(int user){
String sql = "SELECT * FROM expense WHERE _id IN (SELECT id_expense FROM forwho WHERE id_user = ?)";
String[] arguments = {Integer.toString(user)};
return mDb.rawQuery(sql, arguments);
So bacically the problem is when I am using a variable.
Can anyone see where I am messing it up?
Thank you
It should be WHERE id_user = '" + user + "')";
SQL requires single quotes around data on the right of the equals.
try to replace
String sql = "SELECT * FROM expense WHERE _id IN (SELECT id_expense FROM forwho WHERE id_user = "+ user +")";
with
String sql = new String("SELECT * FROM expense WHERE _id IN (SELECT id_expense FROM forwho WHERE id_user = "+ String.valueOf(user) +")");
EDIT: use String.valueOf instead of Integer.toString