I need some help with the SUM feature in android app. I have a table that looks something like the following :
I have need to SUM Quantities between last two records Notes and last one record with Note. I need to sum Quantity of rows 31,32 and 33. It would return 90. I've tried
SELECT Sum(QUANTITY) FROM fuel_table WHERE NOTE!='' ORDER BY ID DESC
but it returns SUM of all quantities with note.
I am inclined to phrase the question as: sum the quantity from all rows that have one note "ahead" of them. This suggests:
select sum(quantity)
from (select ft.*,
(select count(*)
from fuel_table ft2
where ft2.note = 'Yes' and ft2.id >= ft.id
) as numNotesAhead
from fuel_table ft
) ft
where numNotesAhead = 1;
WITH max_id_with_note AS
(
SELECT MAX(ID) AS max_id
FROM YourTable
WHERE IFNULL(note, '') <> ''
)
, previous_max_id_with_note AS
(
SELECT max(ID) as max_id
FROM YourTable
WHERE IFNULL(note, '') <> ''
AND ID < (SELECT max_id FROM max_id_with_note)
)
SELECT SUM(Quantity)
FROM YourTable
WHERE (SELECT max_id FROM previous_max_id_with_note)
< ID and ID <=
(SELECT max_id FROM max_id_with_note)
Example at SQL Fiddle.
First select few ROW and from this selection query SUM(). In your case it looks like this:
Select SUM(t1.QUANTITY) FROM (SELECT QUANTITY from fuel_table WHERE NOTE!='' ORDER BY ID limit 2) as t1
Change your query as
SELECT Sum(QUANTITY) FROM fuel_table ORDER BY ID DESC LIMIT 3
I created table like you have and test. Andomar had good idea but made few mistakes!
WITH max_id_with_note AS
(
SELECT MAX(ID) AS max_id
FROM fuel_table
WHERE Note <> ''
)
, previous_max_id_with_note AS
(
SELECT max(ID) as max_id
FROM fuel_table
WHERE Note <> ''
AND ID < (SELECT max_id FROM max_id_with_note)
)
SELECT SUM(Quantity)
FROM fuel_table
WHERE (SELECT max_id FROM previous_max_id_with_note)
< id and id <= (SELECT max_id FROM max_id_with_note)
Use sub query to get your QUANTITY in deceasing order by ID and LIMIT 3 as you want last 3 row and put SUM() to the result quantity...
SELECT SUM(QUANTITY) FROM (SELECT QUANTITY FROM fuel_table ORDER BY ID DESC LIMIT 3);
Related
I wanted to get information about streaks of certain challenges from my database. I experimented with all of my queries in sqliteonline.com and therefore I found a query which meets my requirements to get these information:
select challengeid, min(date) as min_date, max(date) as max_date, count(*) as length from (select t.*, row_number() over (partition by challengeid order by date) as seqnum from ACTIVE_CHALLENGES_TABLE t) t group by challengeid, date(date, '-' || seqnum || ' day') HAVING challengeid = 4 AND value != 0
Everything works fine on sqliteonline.com, but when it comes to Android Studio I get following error:
android.database.sqlite.SQLiteException: near "(": syntax error (code 1): , while compiling: select challengeid, min(date) as min_date, max(date) as max_date, count() as length from (select t., row_number() over (partition by challengeid order by date) as seqnum from ACTIVE_CHALLENGES_TABLE t) t group by challengeid, date(date, '-' || seqnum || ' day') HAVING challengeid = 4 AND value != 0
I already tried finding out what causes the error. Throughout testing I found out that it could be the use of this snippet: SELECT row_number() OVER (challengeid) seqnum from ACTIVE_CHALLENGES_TABLE
I don't know what I should do. Can you please help me?
If your version of SQLite does not support window functions you can use a correlated subquery to get the column seqnum:
select challengeid, min(date) as min_date, max(date) as max_date, count(*) as length
from (
select t.*,
(
select count(*) + 1 from ACTIVE_CHALLENGES_TABLE
where challengeid = t.challengeid
and (date < t.date or (date = t.date and rowid < t.rowid))
) as seqnum
from ACTIVE_CHALLENGES_TABLE t
where t.challengeid = 4 and t.value != 0
)
group by challengeid, date(date, '-' || seqnum || ' day')
Note that I removed the HAVING clause, which does not make sense since it does not filter out any aggregated columns and I replaced it with a WHERE clause inside the subquery, since you want results only under the condition:
challengeid = 4 and value != 0
I have an application that makes quite a lot of selects, listing its results and allowing the user edit certain values.
The core of my question is if its possible to improve my queries or not given the following query in SQLite:
"SELECT X.data1, X.data2, count(X.id_X) as Quantity_Itens,
(select count(*) from Table2 where id_X=X.id_X) local_Table2,
(select count(*) from Table3 inner join Table2 on Table3.id_Table2 = Table2.id where Table3.id_X=X.id_X and type=1) Quantity_Type1,
(select count(*) from Table3 inner join Table2 on Table3.id_Table2 = Table2.id where Table3.id_X=X.id_X and type=2) Quantity_Type2,
(select count(*) from Table4 where id_X = X.id_X) Quantity_Other,
(select count(*) from Table2 where id_X = X.id_X and status <10) Total_Data FROM Table1 X where (X.type_item = 2 or X.type_item = 4 or X.type_item = 6 or X.type_item = 8) and X.ative = 1 and id_local != 0 group by X.id_X order by X.Alias1"
I am not sure if using promisses will improve in any way this, as I need all those datas before allowing the user to take control again.
Also, may or may not be relevant:
OS: Android 4+
Frameworks: Ionic1, AngularJS, Cordova
In your query there are 5 subqueries executed for each of the rows of Table1.
Only one of them accesses only once 1 table.
2 of them access the same table twice and 2 of them access 2 joined tables twice.
This means there are multiple scans through the same tables for each of the rows of Table1.
Also you are aggregating inside Table1, with GROUP BY id_X, but you have in the SELECT list 2 columns: data1 and data2, which are not included in the GROUP BY clause. This means that the returned values of these columns are arbitrary.
And what is that column Alias1? There is no such column among the returned columns of the query.
Anyway, I suggest that you aggregate first in each table, or join of tables and then join to Table1.
Like this:
SELECT t1.data1,
t1.data2,
t1.Quantity_Items,
t2.local_Table2,
t3.Quantity_Type1,
t3.Quantity_Type2,
t4.Quantity_Other,
t2.Total_Data
FROM (
-- The values returned for data1, data2 and Alias1 will be arbitrary
SELECT id_X, data1, data2, Alias1, COUNT(*) Quantity_Items
FROM table1
GROUP BY id_X
) t1
INNER JOIN (
SELECT id_X, COUNT(*) local_Table2, SUM(status < 10) Total_Data
FROM Table2
GROUP BY id_X
) t2 ON t2.id_X = t1.id_X
INNER JOIN (
SELECT t3.id_X, SUM(type = 1) Quantity_Type1, SUM(type = 2) Quantity_Type2
FROM Table3 t3 INNER JOIN Table2 t2
ON t3.id_Table2 = t2.id
GROUP BY t3.id_X
) t3 ON t3.id_X = t1.id_X
INNER JOIN (
SELECT id_X, COUNT(*) Quantity_Other
FROM Table4
GROUP BY id_X
) t4 ON t4.id_X = t1.id_X
WHERE t1.type_item IN (2, 4, 6, 8)
AND t1.active = 1 AND t1.id_local <> 0
ORDER BY t1.Alias1
I have a table with below rows.
rowid type value
1 A 13
2 A 14
3 B 12
4 B 15
5 C 17
6 C 16
I want to get the bigest value of type A first, it's rowid=2, then others in order by value DESC, the rowids are 56413
How to implement it sqlite? Thanks a lot!
If you wanted to do this only in the order by:
order by (case when type = 'A' and
value = (select max(t2.value) from t t2 where t2.type = 'A')
then 1 else 2
end),
value desc;
Or:
select t.*
from t cross join
(select max(value) as maxvalue from t where type = 'A'
) ta
order by (case when t.type = 'A' and t.value = ta.maxvalue then 1 else 2 end),
value desc;
Simply use the UNION clause to join 2 queries in one.
SELECT Type, Value FROM YourTableName WHERE rowID = 2
UNION
SELECT Type, Value FROM YourTableName WHERE rowID != 2 ORDER BY value DESC
Hello friends i have three tables property_master , rent_master,expense_master and fields are as below
property_master --> p_id, p_name
rent_master --> r_id,p_id,r_amount
expense_master --> e_id,p_id,e_amount
i want to total sum of r_amount, and e_amount with single query so my query is as below
SELECT p.p_id AS "Product Code",
p.p_name AS "Description",
SUM(CASE WHEN ri.r_amount IS NULL THEN 0 ELSE ri.r_amount END) AS "Quantity" ,
SUM(CASE WHEN d.e_amount IS NULL THEN 0 ELSE d.e_amount END) AS "DQuantity"
FROM property_master AS p
LEFT JOIN rent_master AS ri ON ri.p_id = p.p_id
LEFT JOIN expense_master AS d ON d.p_id = p.p_id
GROUP BY p.p_id
ORDER BY SUM(ri.r_amount) DESC,
SUM(d.e_amount) DESC
When i run above code it will give right value for r_amount but for e_amount it will give double value for that so any idea how can i solve this?
When there are two different rent_master rows with the same p_id values, you get two joined rows for each matching expense_master row.
You have to compute the sums with independent subqueries:
SELECT p_id AS "Product Code",
p_name AS "Description",
(SELECT SUM(r_amount)
FROM rent_master
WHERE p_id = property_master.p_id
) AS "Quantity",
(SELECT SUM(e_amount)
FROM expense_master
WHERE p_id = property_master.p_id
) AS "DQuantity"
FROM property_master
ORDER BY Quantity DESC,
DQuantity DESC
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 !!