Android Sqlite remove oldest duplicate results based on date column - android

I have an Android Sqlite database and I'm trying to select the top 1000 rows by RANK number, because RANK is always changing I sometimes get duplicate rows with the same RANK number, what I would like to do is only keep the duplicate row containing the newest RANK based on its CREATED_DATE, I will visually display this below:
id rank created_date
1 1 1/1/2014
2 2 1/1/2021
3 3 1/1/2021
4 1 1/1/2021
The output I want is:
id rank created_date
2 2 1/1/2021
3 3 1/1/2021
4 1 1/1/2021
My current code gets close but doesn't remove duplicate RANK based on CREATED_DATE instead it removes them based on ID which I don't want and I haven't been able to find a way to do it by CREATED_DATE
Cursor c = theDatabase.query(DATABASE_TABLE, columns, RANK + " BETWEEN 1 AND 1000", null,
RANK, null, ID + " ASC");
This code above is removing duplicates based on ID which I don't want and gives this output below:
id rank created_date
1 1 1/1/2014
2 2 1/1/2021
3 3 1/1/2021
Any help will go a long way thanks

you can use GROUP BY with max() function.
e.g. select * from table group by rank having max(created_date)

Related

Android: SQLite update Single value in a col. and then all other of the same col

I have the below table in my DB
id name is_current
1 apple 0
2 banana 1
3 mango 0
4 grapes 1
5 pineapple 1
I want to execute an update query which will update the (fruit) table last column (is_current) single value and at the same time the whole column values as well. For example the first row has an apple with id=1 and I want to set this value to 1 and all other fruit values to zero so the table look like,
id name is_current
1 apple 1
2 banana 0
3 mango 0
4 grapes 0
5 pineapple 0
Currently I am using two different queries and to different methods to achieve this
1st: is to set all values of is_current column to 0
String sql = "UPDATE "+TABLE_NAME +" SET " + is_current + " = '"+ Zero +"';
2nd: is to set the apple values to 1 by using id
String sql = "UPDATE "+TABLE_NAME +" SET " + is_current + " = '"+ One +"' WHERE "+ id + " = "+rowId;
So how can I combine these two queries to a single one to achieve this?
If you want to do this stuff for a specific fruit/ID (e.g. every time you update apples) you can set a trigger such that when you update that fruit, then it will automatically set to zero all other rows.
However if you want to do this stuff in a more general way then you need to perform 2 queries (as told by #Der Golem)
how can I combine these two queries to a single one to achieve this?
You can't.
You have to execute at least 2 commands.
A command to update all the is_current values to 0.
And a command to update the specified record to 1.

SQLite delete one single row

I have a SQLite table defined this way:
CREATE TABLE Points(value INTEGER, player INTEGER, match INTEGER)
In the execution, I may have several identical columns, and I want a call which only deletes one, not all of them nor keeping just one. Is there any SQL call to do that?
An example to explain myself clearer:
value player match
1 2 3
1 3 3
1 2 3
2 2 3
1 2 3
1 2 3
1 3 3
db.delete("Points", "value = 1, player = 2, match = 3", null); //pseudo-code for the deletion
db.delete("Points", "value = 1, player = 3, match = 3", null);
value player match
1 2 3
2 2 3
1 2 3
1 2 3
1 3 3
I think db.delete("Points", "value = 1, player = 3, match = 3", null); will delete ALL columns which match the where clauses, am I right?
The delete statement you wrote will indeed delete all matching rows.
Try to use the built-in column ROWID, read the first line, save the rowid, and then delete where ROWID= the value you selected.
Try this
String _val=""+1;
String _player=""+3;
String _match=""+3;
db.delete(TABLE_NAME,"value=? AND player=? AND match=?",new String[] {_val,_player,_match});
The usual way to do this is to assign every table a unique identifier for each row. Like this:
CREATE TABLE Points(Id INTEGER PRIMARY KEY, value INTEGER, player INTEGER, match INTEGER);
Then you can use a subquery to find the one row you want to delete:
DELETE FROM Points WHERE Id =(SELECT MIN(Id) FROM Points WHERE value=1 AND player=2 and match=3);
This example deletes the oldest record entered first (the oldest has the lowest unique key Id)

SQL sqlite conditional query in sqlite (for Android)

Hello I have a table with that structure:
ID VALUE
1 3
2 5
3 12
if I query select id,value,value+5 from table. Thats the result
ID VALUE NEW_VALUE
1 3 8
2 5 10
3 12 17
And what I want to make a query indicating the id and the new value that return the whole table but with a 3rd column indicating the new values after inserting. for example for myQuery(id=2,value=8)
ID VALUE NEW_VALUE
1 3 3
2 5 8
3 12 12
Is posible to do that in the same query?
YOu can use the WHERE clause to select only the rows you want ("...if the student has the given id..."):
update T
set col3 = col2 + 5
where id = 2
Of course, col3 would have to exist before you can update it. So you will either have to issue an ALTER-TABLE statement (if your implementation supports it) or recreate the table with the desired columns, import the original data (INSERT INTO YOURNEWTABLE...SELECT ... from YOUROLDTABLE) and then update col3.
If you don't want to "persist" this third column but only need it to be displayed when you query:
select id, col2, col2 + 5 as myComputedValue
from T
where id = 2
Finally, if you want to display all rows but change the addend conditionally (add zero to col2 when the id is not one of the ones you desire but add 5 when it is) then you can use the CASE statement.

Need to show a SQLite query in descending order

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 */

How can I count the number of rows before a certain row in sqlite?

I have a database that stores the rank of an Item.
The rank is an absolute value that will be correct if all the items are taken into account.
If I only need a subset say four of this items it will give me something like:
Rank RowId in the whole Table
---------------
4 114
8 71
70 16
83 7
I now need an int specifying the rank only in the subset where the max rank is the number of items in the subset in my example 1,2,3,4.
Is there a way to achieve this in my sqlite query? I only need one of the ranks in my Activity. I thought of ordering the results of the query by rank and then somehow get the position of item I want to rank at that moment. But how would I achieve this with sqlite?
I tried to create a temporary table and insert the subset into it like this:
CREATE TABLE rank(ID);
INSERT INTO position SELECT ID from items WHERE ITEM_ID = 3 ORDER BY POSITION;
SELECT RowID from rank WHERE ID = 9;
DROP TABLE rank;
This is working in SQLite Manager and will return the correct number. But if I do this in Android in fails saying that there is no table rank while compiling query
07-07 13:35:46.150: ERROR/AndroidRuntime(2047): Caused by: android.database.sqlite.SQLiteException: no such table: rank: , while compiling: SELECT RowID from rank WHERE ID = 9
EDIT: have to agree with #Matt the only way I've been able to do this is to use the temp table approach.
For what it's worth here's what it looks like...
create temp table if not exists <temptable>(Id integer primary key, rank);
insert into temptable(rank) select <column> from <table>;
select * from temptable;
EDIT: Actually that returns the ID associated with the row which isn't sequential so you won't always get 1,2,3,4... I'll have to think of something else. Sorry.
Not sure if I've understood your question. You basically want this?
Id Value
---------------
1 4
2 8
3 70
4 83
So you want to add a pseudo-column as the id no matter what your subset contains?
If that's correct then this should do it...
SELECT RowId, <other columns>.... FROM <table> WHERE <where>
Apologies if I've misunderstood.
You could output your query (ordered by rank) into a temporary table with an auto increment ID.
If you need to read only one row from a subquery you can always execute a limit on it, by providing the offset of how many records to be skipped first, and how much to be returned
so if you want to get 25th row you tell to skip 24, and return 1
select * from (SELECT * FROM table order by rank) limit 24,1

Categories

Resources