group and sort sqlite records - android

I have a table with the following cols
_id INTEGER PRIMARY KEY,
body TEXT,
category TEXT,
is_readed INTEGER,
date INTEGER
i have the records look the example
i have the following query
SELECT
_id, body, category, is_readed
FROM
table
GROUP BY
category
ORDER BY
category, is_readed, date DESC
i want show only the first record for category (regardless of whether is_readed is 0 or 1) but i want show first (if exist) the record with is_readed == 1. but sometimes show first record with is_readed == 0 even if exist one with is_readed == 1
Note: I'm using ContentProvider not raw queries
Update
after try a while with this roughly work
SELECT
_id, body, category, MIN(is_readed) as is_readed
FROM
table
GROUP BY
category
ORDER BY
category, date DESC
i still are making tests but I'm still not convinced
Examples
SELECT * FROM table ORDER BY category, is_readed ASC, date DESC;
_id|category|body|is_readed|date
19|Hogar|message1|1|1371449889136
16|Hogar|message2|1|1371449806704
15|Hogar|message2|1|1371449803825
11|Hogar|message3|1|1371448915930
5|Hogar|message4|1|1371447395055
4|Hogar|message4|1|1371447391394
23|Linea blanca|message2|0|1371450430216
26|Linea blanca|message1|1|1371450719124
24|Linea blanca|message4|1|1371450431604
21|Linea blanca|message1|1|1371449893835
20|Linea blanca|message1|1|1371449891488
17|Linea blanca|message3|1|1371449810104
13|Linea blanca|message3|1|1371448994173
12|Linea blanca|message2|1|1371448917864
6|Linea blanca|message4|1|1371447397387
22|Vehiculos|message3|0|1371450428817
14|Vehiculos|message3|0|1371449801144
25|Vehiculos|message4|1|1371450717115
18|Vehiculos|message4|1|1371449887682
10|Vehiculos|message1|1|1371448422563
9|Vehiculos|message4|1|1371448419438
8|Vehiculos|message3|1|1371448416315
7|Vehiculos|message4|1|1371448395644
3|Vehiculos|message3|1|1371447388887
2|Vehiculos|message1|1|1371447386126
1|Vehiculos|message2|1|1371447383557
My Update
SELECT
_id, body, category, MIN(is_readed) as is_readed
FROM
table
GROUP BY
category
ORDER BY
category, date DESC
_id|category|body|is_readed|date
4|Hogar|message4|1|1371447391394
23|Linea blanca|message2|0|1371450430216
14|Vehiculos|message3|0|1371449801144
#Hoan Nguyen answer
4|Hogar|message4|1|1371447391394
6|Linea blanca|message4|1|1371447397387
1|Vehiculos|message2|1|1371447383557
Expected result
19|Hogar|message1|1|1371449889136
23|Linea blanca|message2|0|1371450430216
22|Vehiculos|message3|0|1371450428817

I had to implement raw queries in my ContentProvider and also a subquery, but I think that can be performed without the subquery
SELECT
_id, body, category, is_readed, date
FROM
(
SELECT
_id, body, category, is_readed, date
FROM
table
GROUP BY
is_readed, category
ORDER BY
category ASC, is_readed DESC, date DESC
)
GROUP BY
category

SELECT
_id, body, category, is_readed
FROM
table
GROUP BY
category
HAVING
max (is_readed)
ORDER BY
category, is_readed, date DESC

Related

SqlLiteDatabase.query order by date column not working

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

SQLite subquery

I have a query with a subquery that returns multiple rows.
I have a table with lists and a table with users. I created a many-to-many table between these two tables, called list_user.
LIST
id INTEGER
list_name TEXT
list_description TEXT
USER
id INTEGER
user_name TEXT
LIST_USER
id INTEGER
list_id INTEGER
user_id INTEGER
My query with subquery
SELECT * FROM user WHERE id = (SELECT user_id FROM list_user WHERE list_id = 0);
The subquery works (and I use it in code so the 0 is actually a variable) and it returns multiple rows. But the upper query only returns one row, which is pretty logical; I check if the id equals something and it only checks against the first row of the subquery.
How do I change my statement so I get multiple rows in the upper query?
I'm surprised the = works in SQLite. It would return an error in most databases. In any case, you want the in statement:
SELECT *
FROM list
WHERE id in (SELECT user_id FROM list_user WHERE list_id = 0);
For a better performance, use this query:
SELECT LIST.ID,
LIST.LIST_NAME,
LIST.LIST_DESCRIPTION
FROM LIST,
USER,
LIST_USER
WHERE LIST.ID = LIST_USER.USER_ID = USER.ID AND
LIST.LIST_ID = 0

SQLite ORDER BY result of nested query

I have a table with multiple date fields, and I would like to select the rows with the dates closest to the current date, regardless of which column it is.
There are 2 tables in the database;
Covers:
create table covers (_id integer primary key autoincrement, "
+ "stallionName integer not null, mareName integer not null, firstCoverDate text not null, lastCoverDate text not null, "
+ "scan14Date text not null, scan28Date text not null, foalingDate text not null, inFoal integer not null, notes text not null," +
"FOREIGN KEY (stallionName) REFERENCES horses (_id), FOREIGN KEY (mareName) REFERENCES horses (_id))
stallionName and mareName are integers that reference the row _id of the relevant horse in the horse table (As such, the SQL query has multiple joins to get the names for the stallion and mare, instead of just the row _id). All date columns are of the form 'YYYY-MM-DD'
and horses:
create table horses (_id integer primary key autoincrement, "
+ "name text not null, type integer not null, birthDate text not null, vaccineDate text not null, "
+ "inFoal integer not null, notes text not null)
type is an integer referencing a spinner position (type is either mare, stallion, gelding etc)
I want to select 5 rows from the covers table with values of scan14Date, scan28Date and foalingDate that are nearest to today's date (i.e. the 5 most urgent rows)
This is my effort so far;
SELECT covers.* horses1.name AS stallionNameText, horses2.name AS mareNameText
FROM horses horses1 JOIN covers ON horses1._id = covers.stallionName JOIN horses horses2 ON horses2._id = covers.MareName
WHERE covers._id IN
(SELECT DISTINCT _id FROM
(SELECT covers.scan14Date AS date, covers._id
FROM covers
WHERE date > dateToday
UNION
SELECT covers.scan28Date AS date, covers._id
FROM covers
WHERE date > dateToday
UNION
SELECT covers.foalingDate AS date, covers._id
FROM covers
WHERE date > dateToday
ORDER BY date)
LIMIT 5)
(It can be assumed that 'dateToday' is also of the form YYYY-MM-DD. It's sorted out in java)
Now, the nested query below successfully selects the 5 'most urgent' row _ids;
(SELECT DISTINCT _id FROM
(SELECT covers.scan14Date AS date, covers._id
FROM covers
WHERE date > dateToday
UNION
SELECT covers.scan28Date AS date, covers._id
FROM covers
WHERE date > dateToday
UNION
SELECT covers.foalingDate AS date, covers._id
FROM covers
WHERE date > dateToday
ORDER BY date)
LIMIT 5)
And the first section successfully gets all the data for the row _id selected above;
SELECT covers.* horses1.name AS stallionNameText, horses2.name AS mareNameText
FROM horses horses1 JOIN covers ON horses1._id = covers.stallionName JOIN horses horses2 ON horses2._id = covers.MareName
WHERE covers._id IN
....
The issue I'm having is that the order of the row _ids returned by the nested query is lost in the overall query. If for example the nested query returns the row _ids (6, 3, 4, 12, 15) the overall query displays it in the order (3, 4, 6, 12, 15)
I would then like to return the stallion name, mare name, lastCoverDate, 14ScanDate, 28ScanDate and foalingDate.
My question is how can I maintain the order returned by the inner query? I naively tried to add ORDER BY date at the very end, but it predictably says there is no such column.
Thankyou for taking the time to read.
(Also, I'm sure that my SQL query won't be the most efficient way of doing it, but I'm fairly new to all this)
Include the date in the result of the inner query, then you can order by date in the outer query. Your Java wrapper can simply ignore the date field in the result.

rawquery() issue

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 !!

Strange Problem with Cursor - Android

This is a method In my DataBase Class:
public Cursor fetchFavTitles() {
return myDataBase.rawQuery("SELECT rowid as _id, title
FROM table1 JOIN table2 JOIN table3 JOIN table4 JOIN table5 JOIN table6
WHERE fav = TRUE", null);
}
My SQLite database has 6 tables:
table1 => rowid, title, content, fav
table2 => rowid, title, content, fav
table3 => rowid, title, content, fav
table4 => rowid, title, content, fav
table5 => rowid, title, content, fav
table6 => rowid, title, fav
In my activity, I wrote this:
Cursor cursor = myDbHelper.fetchFavTitles();
and the application forces the close!
Any idea where I'm mistaken ?
UPDATE
This is a snapshot of the LogCat, I couldn't understand it, I filtered the output with android.database:
What I am trying to do is getting the title (type: TEXT) that have a fav (type: BOOL) with value TRUE From all the tables and display them in one ListView (using SimpleCursorAdapter).
Without understanding exactly what you're going for, I'm guessing you need to change your query to:
SELECT rowid as _id, title
FROM table1
WHERE fav = TRUE
UNION ALL
SELECT rowid as _id, title
FROM table2
WHERE fav = TRUE
UNION ALL
SELECT rowid as _id, title
FROM table3
WHERE fav = TRUE
UNION ALL
SELECT rowid as _id, title
FROM table4
WHERE fav = TRUE
UNION ALL
SELECT rowid as _id, title
FROM table5
WHERE fav = TRUE
UNION ALL
SELECT rowid as _id, title
FROM table6
WHERE fav = TRUE
This will take all the results where 'fav = TRUE' from each of the tables and put them all into one result set. If you don't want duplicates, you can change 'UNION ALL' to 'UNION'. Right now your query is failing because 'SELECT rowid as _id, title' doesn't know which of your tables to pull the 'title' field from.

Categories

Resources