How to write this SQL query to find each account balance? - sql

I have a transaction table (shown in picture)
https://i.ibb.co/7pdYxxm/hhhhhh.jpg
There's the transaction type (debit/credit)
I need a SQL query that calculates the balance of each account (sum of credits - sum of debts)
So we group by account_id ... but how can we sum the credits alone and the debits alone?
I am on PostgreSQL! Thank you!

This is an easy method to for you to achieve this:
select account_id, sum((case when transaction_type = 'C' then 1 else 0 end)*transaction_amount) as sum_of_credit,sum((case when transaction_type = 'D'then 1 else 0 end) * transaction_amount) as sum_of_debit from YourTableNameHere group by account_id;
Sample Data
Sample Output for the query

I assume the amount must be substracted when the type = 'C'.
select account_id, sum((case when transaction_type = 'C' then -1 else 1 end) * transaction_amount)
from trans
group by account_id
base on the transaction type the amount is multiplied by 1 or -1.

Try This:
Select sum(Transaction_Amount),
Account_Id,
Transaction_Type
From Table_Name
Group By
Account_Id,
Transaction_Type

Related

SQL - Dividing aggregated fields, very new to SQL

I have list of line items from invoices with a field that indicates if a line was delivered or picked up. I need to find a percentage of delivered items from the total number of lines.
SALES_NBR | Total | Deliveryrate
1 = Delivered 0 = picked up from FULFILLMENT.
SELECT SALES_NBR,
COUNT (ITEMS) as Total,
SUM (case when FULFILLMENT = '1' then 1 else 0 end) as delivered,
(SELECT delivered/total) as Deliveryrate
FROM Invoice_table
WHERE STORE IN '0123'
And SALE_DATE >='2020-02-01'
And SALE_DATE <='2020-02-07'
Group By SALES_NBR, Deliveryrate;
My query executes but never finishes for some reason. Is there any easier way to do this? Fulfillment field does not contain any NULL values.
Any help would be appreciated.
I need to find a percentage of delivered items from the total number of lines.
The simplest method is to use avg():
select SALES_NBR,
avg(fulfillment) as delivered_ratio
from Invoice_table
where STORE = '0123' and
SALE_DATE >='2020-02-01' and
SALE_DATE <='2020-02-07'
group by SALES_NBR;
I'm not sure if the group by sales_nbr is needed.
If you want to get a "nice" query, you can use subqueries like this:
select
qry.*,
qry.delivered/qry.total as Deliveryrate
from (
select
SALES_NBR,
count(ITEMS) as Total,
sum(case when FULFILLMENT = '1' then 1 else 0 end) as delivered
from Invoice_table
where STORE IN '0123'
and SALE_DATE >='2020-02-01'
and SALE_DATE <='2020-02-07'
group by SALES_NBR
) qry;
But I think this one, even being ugglier, could perform faster:
select
SALES_NBR,
count(ITEMS) as Total,
sum(case when FULFILLMENT = '1' then 1 else 0 end) as delivered,
sum(case when FULFILLMENT = '1' then 1 else 0 end)/count(ITEMS) as Deliveryrate
from Invoice_table
where STORE IN '0123'
and SALE_DATE >='2020-02-01'
and SALE_DATE <='2020-02-07'
group by SALES_NBR

Transact SQL - Table with different Record types requiring calculation

I have a table of invoices and Record_Types that I need to reconcile to open invoice report. I have the process down and know what I need to do. Just dont know how to properly structure the query and would prefer to not create 3 tables.
Record Types.
Invoice = 1 Credit = 5 Payment = 7
Invoice_Number, Record_Type, Dollar figure
Outstanding_Balance = Invoice(1) -(Payment(7)-(Credit))
Invoice_number Record_type Gen_Numeric_3
Basically I need to take the record_Type 1 and subtract the total of record type 7's from the below.
Invoice_Num Rec_Type Dollar_Amt
00820437 1 536.7700000000
00820437 7 469.6200000000
00820437 7 67.1500000000
Any advice would be great. messer
You can do this with aggregation and case statements:
SELECT invoice_num,
SUM(CASE WHEN rec_type = 1 THEN dollar_amt ELSE 0 END) - (SUM(CASE WHEN rec_type=7 THEN dollar_amt ELSE 0 END) - SUM(CASE WHEN rec_type=5 THEN dollar_amt ELSE 0 END)) as outstanding_balance
FROM yourtable
GROUP BY invoice_num

Subtract two value by difference criteria in same row

In this table we see different transaction in same date some of Transaction Dr and some transaction Cr. I need Cr - Dr as Transaction Amount per date.
Please see screenshot 1st Table
Result will be-
Result
you could use a case when and group by
select date, sum(case when drcr = 'CR' then amount
when drcr = 'DR' then -amount
else 0 end)
from my_table
group by date
as #scaisEdge but you need a sum.
select date, sum(case when drcr = 'CR' then amuont else (-1 * amount) end) as tran_amt
from my_table
group by date
This should be clear, but the way it works is to add credits and substract debits to the total for each date.

SQL select grouping and subtract

i have table named source table with data like this :
And i want to do query that subtract row with status plus and minus to be like this group by product name :
How to do that in SQL query? thanks!
Group by the product and then use a conditional SUM()
select product,
sum(case when status = 'plus' then total else 0 end) -
sum(case when status = 'minus' then total else 0 end) as total,
sum(case when status = 'plus' then amount else 0 end) -
sum(case when status = 'minus' then amount else 0 end) as amount
from your_table
group by product
There is another method using join, which works for the particular data you have provided (which has one "plus" and one "minus" row per product):
select tplus.product, (tplus.total - tminus.total) as total,
(tplus.amount - tminus.amount) as amount
from t tplus join
t tminus
on tplus.product = tminus.product and
tplus.status = 'plus' and
tplus.status = 'minus';
Both this and the aggregation query work well for the data you have provided. In other words, there are multiple ways to solve this problem (each has its strengths).
you can query as below:
select product , sum (case when [status] = 'minus' then -Total else Total end) as Total
, sum (case when [status] = 'minus' then -Amount else Amount end) as SumAmount
from yourproduct
group by product

SQL: how to aggregate value with conditions (CASE WHEN???)

My data has 3 variables, User ID, Transaction Amount, and Transaction Date,
I want to aggregate 2 day transaction amount for each user ID, but with conditions.
The condition is, for example, I want to aggregate 8/31 and 8/30 transaction amount for an ID 12345, if the transaction amount is 0 on 8/31 for this ID, which means this ID does not have any transactions on 8/31, then just ignore this user ID, I'm not going to aggregate amount for this user ID.
If another ID 23456 has transactions on 8/31 and does not have transaction on 8/30, then I will aggregate the transactions on 8/31 for this ID.
If one ID 34567 has transactions on both 8/30 and 8/31, then I will have aggregate the transactions for both 8/30 and 8/31.
How can I do this? I've been struggling for the whole afternoon. Thanks in advance for any suggestions and idea!
Based on your question should be
select user_id, sum(a.transaction_amount + b.transaction_amount).
from my_table as a
inner join my_table as b on date_add(b.transaction_date, interval 1 day) = a.transaction_date
where date(a.transaction_date) = STR_TO_DATE('31,8,2016','%d,%m,%Y')
and a.transaction_amount > 0
group by user_id
SELECT User_ID, SUM(Transaction_Amount)
FROM yourTable
WHERE DATE(Transaction_Date) = '2016-08-30'
OR (DATE(Transaction_Date) = '2016-08-31' AND Transaction_Amount > 0)
GROUP BY User_ID
Just use conditional aggregation:
select userid,
sum(case when date = '2016-08-30' then amount else 0 end) as amt_20160830,
sum(case when date = '2016-08-31' then amount else 0 end) as amt_20160831
from t
group by userid
having sum(case when date = '2016-08-31' then amount else 0 end) > 0;
Exactly what the code looks like might vary by databases, but this is fairly standard SQL.
Seems like you want to return only users which had a transaction on Aug. 31.:
select userid,
sum(trans_amount)
from t
where trans_date between date '2016-08-30' and date '2016-08-31'
group by userid
having max(trans_date) = date '2016-08-31'