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).
Related
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;
I am new to Windows functions (lag, lead etc) and I am using Oracle. I did some research and tried few solutions but I couldnt get the desired result.
I have an inventory table, where I want to find out the items used and the remaining item left on the given day.
The data comes in as follows
Dates | Items | Total_Inv_Items | Damaged_Items | Sellable_Items | Sold_Items | Remaining_Items
11/13/2020 Pen 999 15 984 109 875
11/13/2020 Book 401 6 386 109 277
11/14/2020 Pen 0 0 0 121 0
11/14/2020 Book 0 0 0 121 0
11/15/2020 Pen 0 0 0 31 0
11/15/2020 Book 0 0 0 31 0
11/16/2020 Pen 201 3 198 33 165
11/16/2020 Book 301 5 296 33 263
Useable_Items and Remaing_Items are caluclated columns.
Sellable_Items = Total_Inv_Items - Damaged_Items
Remaning_Items = Sellable_Items - Sold_Items
Total_Inv_Items is manufacture or new items available in the store.
The desired output:
Dates | Items | Total_Inv_Items | Damaged_Items | Sellable_Items | Sold_Items | Remaining_Items
11/13/2020 Pen 999 15 984 109 875
11/13/2020 Book 401 6 386 109 277
11/14/2020 Pen 0 0 875 121 754
11/14/2020 Book 0 0 277 121 156
11/15/2020 Pen 0 0 754 31 721
11/15/2020 Book 0 0 156 31 125
11/16/2020 Pen 201 3 919 33 886
11/16/2020 Book 301 5 421 33 388
The remanining item is cummulative and the sellable items changes whenever there is a new item added to the inventory or it is same as previous days remaining item.
Query that gives me first data
SELECT
Date,
Items,
NVL(Total_Inv_Items, 0) as Total_Inv_Items,
NVL(Round(Total_Inv_Items * DamagePercentage/100), 0) as Damaged_Item,
Round(Total_Inv_Items - (Total_Inv_Items * DamagePercentage/100)) as Sellable_Items,
Sold_Items,
Round(Total_Inv_Items - (Total_Inv_Items * DamagePercentage/100))- Sold_Items as Remaining_Items
FROM
Table
Order By
Date
Note:
If you notice on Nov 16th there was new items that was available in the store so it adds to the previous days remaining items(Ex Pen 201-3+721).
You can use the lag function as follows:
SELECT Date,
Items,
Total_Inv_Items,
Damaged_Item,
-- FOLLOWING IS CALCULATED EXPRESSION BASED ON YOUR FORMULA: Pen 201-3+721
Total_Inv_Items
- Damaged_Item
+ COALESCE(LAG(Remaining_Items) OVER (PARTITION BY ITEMS ORDER BY DATE),0) AS Sellable_Items,
-- EXPRESSION ENDS HERE
Sold_Items,
Remaining_Items
FROM
(SELECT DISTINCT
Date,
Items,
NVL(Total_Inv_Items, 0) as Total_Inv_Items,
NVL(Round(Total_Inv_Items * DamagePercentage/100), 0) as Damaged_Item,
Round(Total_Inv_Items - (Total_Inv_Items * DamagePercentage/100)) as Sellable_Items,
Sold_Items,
Round(Total_Inv_Items - (Total_Inv_Items * DamagePercentage/100))- Sold_Items as Remaining_Items
FROM Table)
Order By Date
This expression should be placed in the outer query. The inner query should be your query which is giving the first data.
I think you just want cumulative sums and arithmetic:
select t.*,
sum(total_inv_items - damaged_items) over (partition by item order by date) as sellable_items,
sum(total_inv_items - damaged_items - sold_items) over (partition by item order by date) as remaining_items
from t
order by date;
Thanks #Gordon Linoff and #Tejash, your comments helped me to resolve this issue. The following code gave me the desired result.
NOTE: 1.5 is the pecentage of Damaged Items which I have included it directly in the query, most of the time its comes from the DB.
SELECT
Dates,Items,
Total_Inv_Items,
Damaged_Item,
CASE
WHEN Total_Inv_Items = 0 THEN LAG(Remaining_Items) OVER (partition by items order by dates)
ELSE Sellable_Items+NVL(LAG(Remaining_Items) OVER (partition by items order by dates),0)
END as Sellable_Items,
Sold_Items,
Remaining_Items
FROM
(
SELECT
Dates,Items,
Total_Inv_Items,
Damaged_Item,
Sellable_Items,
Sold_Items,
SUM(Sellable_Items - Sold_Items) OVER (partition by items order by dates) as Remaining_Items
FROM
(
SELECT
Dates,
Items,
NVL(Total_Inv_Items, 0) as Total_Inv_Items,
NVL(Round(Total_Inv_Items * 1.5/100), 0) as Damaged_Item,
Round(Total_Inv_Items - (Total_Inv_Items * 1.5/100)) as Sellable_Items,
Sold_Items,
Round(Total_Inv_Items - (Total_Inv_Items * 1.5/100))- Sold_Items as Remaining_Items
FROM
Table T
) A
)B
Order By
Dates
I have a record of users' purchasing behavior. However, it is long and includes a lot of redundant data. I want to delete orders that purchased and deleted within 5 min
My query so far:
--TABLE 3 COD
select z.user_id,
z.date,
z.actions,
x.name,
x.email,
x.address
sum(z.debit) over (partition by z.seller_id order by z.created_at) -
sum(z.credit) over (partition by z.seller_id order by z.created_at)
as balance
from table_1 z
left join
table_2 x
on z.seller_id = x.uid
order by seller_id, created_at
For simplicity, i got this result
user actions credit debit balance date
1 do_action_A 5000 0 5000 2020-01-01 1:00:00 #no need these 2
1 cancel_A 0 5000 0 2020-01-01 1:03:00 #in result
1 do_action_A 5000 0 5000 2020-01-01 1:10:00
1 do_action_b 3000 0 8000 2020-01-01 1:20:00
1 do_action_c 0 7000 1000 2020-01-01 1:30:00
2 do_action_A 5000 0 5000 2020-01-01 1:00:00
2 do_action_B 3000 0 8000 2020-01-01 1:10:00
We know that users can only cancel their orders within 5 minutes, unfortunately, there is a lot of cancels. I need to make this data table simple and short so as to track and visualize it easily.
Here is my expectataion:
user actions credit debit balance date
1 do_action_A 5000 0 5000 2020-01-01 1:10:00
1 do_action_b 3000 0 8000 2020-01-01 1:20:00
1 do_action_c 0 7000 1000 2020-01-01 1:30:00
2 do_action_A 5000 0 5000 2020-01-01 1:00:00
2 do_action_B 3000 0 8000 2020-01-01 1:10:00
You can try using lead()
select * from
(
select z.user_id,z.date,z.actions,x.name,
x.email,x.address,debtit, credit, balance,
lead(z.actions) over(parition by z.user_id order by z.created_at) as next_action
from table_1 z left join table_2 x
on z.seller_id = x.uid
)A where next_action not like '%cancel%' and actions not like '%cancel%'
#i have two tables buyers table and sales table#
buyers table
|buyer | balance|
sales table
|buyer | sales|buydate|
I have tried the following select query
Dim connection As OleDbConnection
Dim adapter As OleDbDataAdapter
Dim ds As New DataSet
Dim SQLStr As String
Dim cmd As OleDbCommand
connection = New
OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data
Source=consignacion.mdb;")
SQLStr = "SELECT b.buyer as [Buyer],b.balance as
[Balance],SUM(s.total) as [Sales],
b.balance+SUM(s.total) as [Total] From buyerdb b
INNER Join salesdb s on b.buyer=s.buyer
WHERE s.total Is Not NULL And
s.buydate =#buydate And
s.total<>#sales AND
b.balance> #balance
GROUP By b.buyer,b.balance"
SQLStr = "SELECT b.buyer as [Buyer],b.balance as
[Balance],SUM(s.total) as [Sales],
b.balance+SUM(s.total) as [Total] From buyerdb b
INNER Join salesdb s on b.buyer=s.buyer
WHERE s.total Is Not NULL And
s.buydate =#buydate And s.total<>#sales AND b.balance> #balance
GROUP By b.buyer,b.balance"
cmd = New OleDbCommand(SQLStr, connection)
cmd.Parameters.AddWithValue("#buydate", Form1.Lbldate2.Text)
cmd.Parameters.AddWithValue("#balance", 0)
cmd.Parameters.AddWithValue("#sales", "")
I expect the output to be
buyer balance sales total
CESS 350 984 1334
DARWIN 0 345 345
GLEN 1000 4334 5334
GLENDA 0 170 170
JOSE 1000 2240 3240
LITO 0 120 120
LOUIE 0 280 280
TANIS 0 2250 2250
YOLLY 1500 832 2332
michael 1500 [null/norecor] 1500
Dudice 700 [null/norecord] 700
but the output is
buyer balance sales total
CESS 350 84 334
> DARWIN 0 345 345
> GLEN 1000 4334 5334
> GLENDA 0 170 170
> JOSE 1000 2240 3240
> LITO 0 120 120
> LOUIE 0 280 280
> TANIS 0 2250 2250
> YOLLY 1500 832 2332
it is not displaying buyers with balance but no recorded sales on the given buydate
i have tried everything i know. i even search google and youtube and seems can't get the right output on my data grid view.
If i asked you to show me something that didn't exist, you couldn't because it doesn't exist. It's the same with NULLS in databases. They signify that something doesn't exist, so it's impossible for the database to show you nothing.
What you can do is use the ISNULL statement to replace the NULLS with an actual value. Try changing your select statement like this:
SELECT b.buyer as [Buyer],b.balance as
[Balance],SUM(ISNULL(s.total,0)) as [Sales] .........
This will replace all NULLS in s.total with a value of 0.
Say I have the following data in my table;
tran_date withdraw deposit
25/11/2010 0 500
2/12/2010 100 0
15/12/2010 0 300
18/12/2010 0 200
25/12/2010 200 0
Suppose I want to get the following for date range between 1/12/2010 and 31/12/2010.
tran_date withdraw deposit balance days_since_last_tran
1/12/2010 0 0 500 0
2/12/2010 100 0 400 1
15/12/2010 0 300 700 13
18/12/2010 0 200 900 3
25/12/2010 200 0 700 7
31/12/2010 0 0 700 6
Is this doable in PostgreSQL 8.4?
Use:
SELECT t.tran_date,
t.withdraw,
t.deposit,
(SELECT SUM(y.deposit) - SUM(y.withdrawl)
FROM YOUR_TABLE y
WHERE y.tran_date <= t.tran_date) AS balance,
t.tran_date - COALESCE(LAG(t.tran_date) OVER(ORDER BY t.tran_date),
t.tran_date) AS days_since_last
FROM YOUR_TABLE t
8.4+ is nice, providing access to analytic/windowing functions like LAG.