get values based on foreign key - android

i have two tables:
Acounts:
ID Name
1 cash
2 bank
3 credit card
Transactions
ID accounts_id details income expenses
1 1 abc 1000 0
2 1 xyz 0 500
3 2 avc 200 0
what i want is to get the sum of income and expenses column for all the accounts in account table (even if there is not record in the transaction table for that account_id)
required output:
account_id total_income total_expenses
1 1000 500
2 200 0
3 0 0
what i am trying in sql:
select account_id,coalesce (sum(income),0) as total_income,coalesce(sum(expenses),0) as total_expenses from transactions where account_id in (select id as accounts_id from accounts) group by account_id
what the above query gives:
account_id total_income total_expenses
1 1000 500
2 200 0
account with ID=3 is not included in the result..
i know i am doing something wrong.. or may be completely wrong..
Thanks in advance.

You need to get all the accounts in the account table. To do that, you need a join, specifically an outer join:
select a.account_id, coalesce(sum(t.income),0) as total_income,
coalesce(sum(t.expenses),0) as total_expenses
from accounts a left join
transactions t
on a.account_id = t.account_id
group by a.account_id;
Your attempt to do this in the where clause is counterintuitive. The where clause filters values, so it reduces the number of rows; it cannot increase the number.

WITH TEMP AS
(
SELECT A.ID,T.*
FROM ACCOUNTS A INNER JOIN TRANSACTIONS T
ON A.ID=T.ID
)
SELECT ACCOUNT_ID,SUM(INCOME) AS INCOME,SUM(EXPENSE) AS EXPENSE FROM TEMP
GROUP BY ACCOUNT_ID;

Related

Read data from two tables

Consider the tables listed below
Table credit
id cr_amount created_date
1 1000 2011-07-01
2 2000 2011-07-08
3 6000 2011-07-09
And Table debit entries are follows.
id dr_amount created_date
1 3000 2011-07-09
Need to read columns cr_amount, dr_amount and created_date from above tables in ordered by created date as shown below.
cr_amount dr_amount created_date
1000 NULL 2011-07-01
2000 NULL 2011-07-08
6000 NULL 2011-07-22
NULL 3000 2011-07-09
You may need to put both columns in the union all:
select cr_amount,Null as 'db_amount',created from table_credit
union all
select Null,db_amount,created from table_debit
order by created

SQLITE, Group by range of 1000s

I have a database of two columns in sqlite for android
id (INT) | owner (VARCHAR)
1477 jack
1578 jill
: :
9277 hill
1)
i like to get a count of the following: -
(group by the 1000s range)
RANGE | COUNT
0-999 0
1000-1999 5
:
8999-9999 7
2)
I also like to get a count of the following: -
(group by 100s range)
RANGE | COUNT
X1XX 5
X2XX 6
:
X9XX 7
3) and also group by 10s range.
I'm stuck with how to do the group by
SELECT COUNT(*) FROM myTable
GROUP BY ??
any pointers is appreciated.
Integer division by integers in sqlite3 yields integers:
select id/1000 as range_id, count(*) as range_count from mytable group by range_id;
To group by 100 ids, simply change 1000 to 100
sqlite3 has a printf() function that might be useful in make a pretty column to describe the range if you need something prettier than the integer division of id by group size.

How to update multiple rows (not ever row) with same value?

My table tbl1 looks like this (SQLFiddle):
id col1 col2 col3
1 0 1 0
2 1 0 0
3 0 0 1
4 1 1 1
5 0 0 0
My requirement is that I get some positive number from the user for each column, and I need to update the rows of a particular column if they contain zero, and finally I should count the number of rows updated and the difference between the user input and the updated count I should add to the last row.
Let me explain with example:
Say user inputs 10 for col1. col1 has 3 rows containing zero so I will update them to 1, and finally the diff i.e. (10 - 3 = 7) I should update in the last row.
After the update I expect the table to look like this:
id col1 col2 col3
1 1 1 0
2 1 0 0
3 1 0 1
4 1 1 1
5 8 0 0
update tbl1 set col1=1 where id in (select id from tbl1 where col1=0 limit 10)
The above query updates all 0s to 1, but how do I add the remaining to last row?
To accomplish your task, I would use 2 update queries. The first one would be the query you already have:
UPDATE tbl1 SET col1=1 WHERE id IN (SELECT id FROM tbl1 WHERE col1=0 LIMIT 10);
I would save the result from the first update query in a variable (since it returns the number of rows affected), and use that result in my next query:
UPDATE tbl1 SET col1 = col1+updateResult ORDER BY id DESC LIMIT 1;
(updateResult is what is returned from the first update query).
I hope this helps.
First, find out how many rows will be updated:
SELECT COUNT(*)
FROM tbl1
WHERE id IN (SELECT id
FROM tbl1
WHERE col1 = 0
LIMIT 10)
The update those:
UPDATE tbl1
SET col1 = 1
WHERE id IN (SELECT id
FROM tbl1
WHERE col1 = 0
ORDER BY id
LIMIT 10)
(Without ORDER BY, some random set of ten rows would be updated.)
Then update the last row:
UPDATE tbl1
SET col1 = col1 + (10 - ResultFromAbove)
WHERE id = (SELECT MAX(id)
FROM tbl1)
To ensure consistency, do everything in a single transaction.

Android SQLite MAX function issue

I want to retrieve rows from table having MAX(col), but MAX(col) return multiple rows if values at col has same data.
I have 2 tables as below:
**Table1**
row_id INTEGER (Primary key auto incremented),
name TEXT
**Table2**
row_id INTEGER (Primary key auto incremented),
ref_id INTEGER (Foreign key of Table1(row_id)),
date_in_long TEXT,
data TEXT
Following query I am performing to get rows having MAX(date_in_long), expecting single latest entered rows.
SELECT DISTINCT a.name, b.row_id, b.ref_id, b.date_in_long, b.data
FROM Table1 a, Table2 b
WHERE a.row_id=b.ref_id
AND b.date_in_long =
(SELECT MAX(c.date_in_long)
FROM Table2 c
WHERE c.ref_id=a.row_id
)
Output result would be perfect if date_in_long is having different values against ref_id.. but it returns multiple rows is values are same.
Example
Table1:
row_id name
1 aparna
2 user1
3 XYZ
Table2:
row_id ref_id date_in_long data
1 1 98 data1 for aparna
2 1 100 data2 for aparna
3 1 100 data3 for aparna
4 2 200 data1 for user1
5 2 300 data2 for user1
6 3 100 data1 for XYZ
Result of above query:
row_id ref_id name date_in_long data
2 1 aparna 100 data2 for aparna
3 1 aparna 100 data3 for aparna
5 2 user1 300 data2 for user1
6 3 XYZ 100 data1 for XYZ
Expected result should be:
row_id ref_id name date_in_long data
3 1 aparna 100 data3 for aparna
5 2 user1 300 data3 for user1
6 3 XYZ 100 data1 for XYZ
Please let me know how issue in above query.
Adding below condition(As solution provided by Alexandar with this post) excluding some rows
AND
b.row_id = (Select MAX(c.row_id) from Table2 c where c.ref_id = b.ref_id)
Output after adding above row_id condition:
row_id ref_id name date_in_long data
3 1 aparna 100 data3 for aparna
6 3 XYZ 100 data1 for XYZ
No rows for USER1.
Please let me know how to solve this query.
Thank you,
Regards,
Aparna
The issue is that the "distinct" keyword doesn't mean "return rows where every value is different from every other row", it means "return rows that are in some way different from each other row".
So even though row_id 2 and 3 have the same ref_id, they have a different row_id and data column- Hence, they're unique rows.
One option is to add an extra condition so that only the max row_id for a specific ref-id is respected.
The added condition would look something like this.
AND
b.row_id = (Select MAX(c.row_id) from Table2 c where c.ref_id = b.ref_id)
Following query solve my issue.
SELECT a.name, b.row_id, b.ref_id, b.date_in_long, b.data, MAX(date_in_long)
FROM Table1 a INNER JOIN Table2 b
ON a.row_id=b.ref_id
GROUP BY a.row_id
Thank you,
Regards,
Aparna

SQLite Query not getting actual count

I'm having a problem with getting the count of the total passenger and baggage on the specific place.
This is my table,enter image description here
but my query shows the total passenger is always 2,
enter image description here
and lastly, this is the query
select
ticket_placeto,
(select count(*) as count from tickets where passenger_type <> 'Baggage' group by ticket_placeto)as Pass ,
ifnull((select count(*) as count from tickets where passenger_type = 'Baggage' group by ticket_placeto),0) as Baggage
from tickets
Rephrase your query to use conditional aggregation:
SELECT
ticket_placeto,
COUNT(CASE WHEN passenger_type <> 'Baggage' THEN 1 END) AS Pass,
COUNT(CASE WHEN passenger_type = 'Baggage' THEN 1 END) AS Baggage
FROM tickets
GROUP BY ticket_placeto;
The idea here is that for each ticket_placeto group you want to take two conditional counts depending on the passenger type.

Categories

Resources