How to query for amount waived for every contract status? - sql

I have 2 tables:
Table 1 "contract" is as the following (sample only):
contract_id
contract_status
111
Active
122
Active
133
Finished
144
Active
155
Finished
contract_status values are: Active and Finished
Table 2 "ledger" is as the following (sample only):
ledger_id
contract_id
ledger_status
amount
1gh
111
WAIVED
450
2uk
111
PAID
0
2jz
111
WAIVED
200
4bc
122
PAID
0
5jw
122
UNPAID
150
3xs
133
PAID
0
9kd
133
WAIVED
250
7bf
144
WAIVED
100
8aq
155
UNPAID
700
One contract can have a lot of ledger_id
How can I calculate the total amount that has been waived for each contract status (active and finished)?
Expected output
contract_status
total_amount_waived
Active
750
Finished
250

We can try a join aggregation approach:
SELECT c.contract_status, COALESCE(SUM(l.amount), 0) AS total_amount_waived
FROM contract c
LEFT JOIN ledger l
ON l.contract_id = c.contract_id AND
l.ledger_status = 'WAIVED'
GROUP BY c.contract_status;

Related

Dynamically Column Creation as per Branch Data

I need to get result from Existing Table and my current result is like
Code Name Branch Dr Cr Net
1001 Closing Stock UP 150000 195000 -45000
1001 Closing Stock DL 159.74 0 159.74
1001 Closing Stock CH 0 24.37 -24.37
1002 IGST Payable UP 0 135.37 -135.37
1002 IGST Payable DL 0 200 -200
1002 IGST Payable CH 200 0 200
1003 Sundry Debtors UP 15767000 0 15767000
1003 Sundry Debtors DL 0 181716 -181716
Note :
If Branches Increase then Branch wise (Debit,Credit,Net) Fields should be Create automatically.
And Result should be like this
Code Name UPDr UPCr UPNet CHDr CHCr CHNet DLDr DLCr DLNet
1001 Stk 1500 1950 -450 0 24.37 -24.37 159 0 159.74
1002 IGST 0 135.37 -135 200 0 200 0 181 -181
1003 Sund 157 0 157 159 0 159 200 0 200
Please help for the same.

Cumulated Cohorts in SQL

I have the following table :
cohort
month cohort
orders
cumulated orders
2021-01
0
126
126
2021-01
1
5
131
2021-01
2
4
135
2021-02
0
131
131
2021-02
1
9
140
2021-02
2
8
148
And now I want to have the following table where I divide each repeat orders by the number of orders of month 0 :
cohort
month cohort
orders
cumulated orders
cumulated in %
2021-01
0
126
126
100%
2021-01
1
5
131
104%
2021-01
2
4
135
107%
2021-02
0
131
131
100%
2021-02
1
9
140
107%
2021-02
2
8
148
114%
My only hint is to create a CASE statement, but I don't want each month to update the query by adding the line
WHEN cohort="2021-08" THEN cumulated orders / 143
where 143 is the number of orders of cohort 2021-08 at month cohort =0
Has someone got an idea how to get this table ?
A case expression isn't needed. You can use first_value():
select t.*,
( cumulated_order /
first_value(orders) over (partition by cohort order by month_cohort)
) as ratio
from t;
If you really wanted a case, you could use:
select t.*,
( cumulated_order /
max(case when month_cohort = 0 then orders end) over (partition by cohort)
) as ratio
from t;
Consider below
select *,
round(100 * cumulated_orders /
sum(if(month_cohort = 0, orders, 0)) over(partition by cohort)
) as cumulated_in_percent
from `project.dataset.table`
if applied to sample data in your question - output is

Cumulative Stock Holding

I am trying to create a stock holding based on the below data.
Input and Desired Output
I have tried using creating a transactions column (Starting + UK Open POs - UK Sales).
Then used the below SQL code to create a stock holding.
Sum OVER ( TRANSACTIONS)
[ <PARTITION BY No_ ]
[ <ORDER BY Date ]
But the problem is I don't want the stock holding to go into a negative. I want it to show 0, so when 960 units come in on 14/04/19 the stock holding is 921 units (960-39) instead of 116 units.
The column highlighted in yellow is my desired output. I need this over 5k SKUs (column no_)
Any help would be very appreciated.
No_ Date UK-Open PO UK-Sales Starting Stock Trans. Cumul Stock Stock Level
111111 22/03/2019 47 100 53 53 53
111111 24/03/2019 330 -330 -277 0
111111 31/03/2019 443 -443 -720 0
111111 07/04/2019 85 -85 -805 0
111111 14/04/2019 960 39 921 116 921
111111 21/04/2019 960 112 848 964 1769
111111 28/04/2019 100 -100 864 1669
111111 05/05/2019 504 -504 360 1165
111111 12/05/2019 606 -606 -246 559
111111 19/05/2019 118 -118 -364 441
111111 26/05/2019 400 -400 -764 41
111111 02/06/2019 674 -674 -1438 0
111111 09/06/2019 338 -338 -1776 0
111111 16/06/2019 206 -206 -1982 0
111111 23/06/2019 115 -115 -2097 0
111111 30/06/2019 500 66 434 -1663 434
111111 07/07/2019 33 -33 -1696 401
Suppressing the negative numbers as you are doing requires remembering what has happened on all previous rows. Alas, this can't be done using window function.
The alternative is a recursive CTE:
with t as (
select no_, date, starting_stock, trans,
row_number() over (partition by no_ order by date) as seqnum
from <table>
),
cte as (
select no_, date, trans, seqnum,
starting_stock as stock_level
from t
where seqnum = 1
union all
select t.no_, t.date, t.trans, t.seqnum,
(case when cte.starting_stock + t.trans < 0 then 0
else cte.starting_stock + t.trans
end) as stock_level
from cte join
t
on t.seqnum = cte.seqnum + 1 and
t.no_ = cte.no_
)
select *
from cte
option (maxrecursion 0);
You only need the option if the number of rows exceeds 100 from the recursion.

datagridview 2 table wrong output

Given the following code:
connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=consignacion.mdb;")
SQLStr = "Select buyer,balance,
(SELECT SUM(salesdb.total)
From salesdb
Where salesdb.buyer = buyerdb.buyer and
buydate=#buydate and
salesdb.total is not Null and
salesdb.total<>#sales ) As [paid]
From buyerdb where balance>#balance"
cmd = New OleDbCommand(SQLStr, connection)
cmd.Parameters.AddWithValue("#buydate", Form1.Lbldate2.Text)
cmd.Parameters.AddWithValue("#balance", 0)
cmd.Parameters.AddWithValue("#sales", 0)
And below the ouput:
name balance sales
BANAL 1000
BAYA 500
RICKY 350
GEN 0
CASH 0
BAGON 0
LOREY 0
TANIS 0 2250
DARWIN 0 345
GLEN 1000 4334
LITO 0 505
LIZA 0 460
CESS 350 984
LOUIE 0 280
YOLLY 0 832
GLENDA 0 170
JOSE 1000 2240
I want to get the followed output:
name balance sales
BANAL 1000
BAYA 500
RICKY 350
TANIS 0 2250
DARWIN 0 345
GLEN 1000 4334
LITO 0 505
LIZA 0 460
CESS 350 984
LOUIE 0 280
YOLLY 0 832
GLENDA 0 170
JOSE 1000 2240
i wanted to display all buyers with balance > 0
i wanted to display all buyer with sales/total >0 at a given date. (sometimes buyers dont have record of sales on a given date.
i don't want to display buyers with balance and sales/total is zero at the same time.
First, use an LEFT JOIN between buyerdb b and salesdb s on the buyer key, and perform a SUM() on these records according a GROUP BY command. It will display buyerdb rows (the left table) even if there are no corresponding salesdb rows:
SELECT b.buyer, b.balance, SUM(s.total) as total
FROM buyerdb b
LEFT JOIN salesdb s on (b.buyer = s.buyer AND s.buydate = #buydate)
GROUP BY buyer
Then, use this request as a nested one, and filtered to get only the rows you want:
SELECT t.buyer, t.balance, t.total
FROM
(
SELECT b.buyer, b.balance, SUM(s.total) as total
FROM buyerdb b
LEFT JOIN salesdb s on (b.buyer = s.buyer AND s.buydate = #buydate)
GROUP BY buyer
) t
-- Filter the rows you don't want (both zero balance and total)
WHERE balance > 0 or total > 0
Working SQL fiddle (should work with Access).

Need to create third table based on ID range in first table and line items in second table

The first table contains a range of account IDs for a company.
Table 1 Company
CID Minacct Maxacct
1 100 200
2 300 350
3 500 700
The second table contains line items for balances in accounts. The key to this problem, is that not all accounts are used in an account range from table 1. For ex., Company 1 could have account IDs from 100 to 200, but in actuality only has 100, 105, 118, and 170.
Table 2 Accts
AcctID Balance
100 $5
105 $10
118 $15
170 $20
300 $25
325 $30
350 $35
501 $40
502 $45
503 $50
602 $55
700 $60
Need to create Table 3 that combines Tables 1 and 2, hopefully using a nifty Select and not a slow loop.
CID AcctID Bal
1 100 $5
1 105 $10
1 118 $15
1 170 $20
2 300 $25
2 325 $30
2 350 $35
3 501 $40
3 502 $45
3 503 $50
3 602 $55
3 700 $60
Thanks!!
David
This is a join query but the join condition is an inequality:
select c.cid, a.*
from accts a join
company c
on a.acctid between c.minacct and c.maxacct;