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
Related
I have a table in my database which has 3 columns: id, name, category_id which has 1 million rows. the user selects a category_id in the app and then the database has to return 12 rows which have the selected category_id. then in the next api call, the database has to return the next 12 rows which have the selected category_id and so on.
My question is how I can return the rows randomly and avoid returning repeated rows in next api calls?
You are looking for a repeatable random sort. For this you can use RAND() with a seed. The idea is that each search should be assigned a constant seed (that you can persist in the user's session, for example).
Assuming that a user has seed 12345, you can fetch its first page like:
select * from mytable where category_id = ? order by rand(12345) limit 12
Then the second page is fetched as follows:
select * from mytable where category_id = ? order by rand(12345) limit 12, 12
Third page:
select * from mytable where category_id = ? order by rand(12345) limit 24, 12
And so on.
Assuming id is a key of the table and has positive values only, you can do:
select id, name, category_id
from my_table
where category_id = ? and id > ?
order by id
limit 12
The first time you call it, you can use:
category_id = 123
id = -1
The second time you get the max id from before (let's say 25) and use that one.
category_id = 123
id = 25
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 am using the following query to get the list of item
Query="Select * from Item_List where idSubcategory = (Select _id from SubCategory_List where Name = ?)";
c = db.rawQuery(Query, new String[] { Search });
But it is returning no result.
I ran this query on the database which I pulled from the device as well as emulator. There I am getting proper result, But when I run it on device no data is returned.
Can you try a different way? Use execSQL() as explained in this link. It is exactly the same problem.
EDIT
Unfortunately i didn't notice that execSQL() return no data (the work day is ending, finally!). The only solution i have is to do a first query and the result of this one will be the parameter of second query.
EDIT 2
Try to add "IN" to your query, like this:
Query = "Select * from Item_List where idSubcategory in (Select _id from SubCategory_List where Name = ?)"
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
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 */