Interesting question for you all. Here's a sample of my dataset (see below). I have warehouses, dates, and the change in inventory level at that specific date for a given warehouse.
Ex: Assuming 1/1/2018 is first date, warehouse 1 starts out with 100 in inventory, then 600, then 300, then 500...etc.
My question I'd like to answer in SQL: By warehouse ID, did each warehouse ever have inventory of more than 750 (yes/no)?
I can't sum the entire column, because the ending inventory (sum of column by warehouse) is likely lower than a past inventory level. Any help is appreciated!!
+--------------+------------+---------------+
| Warehouse_id | Date | Inventory_Amt |
+--------------+------------+---------------+
| 1 | 1/1/2018 | +100 |
| 1 | 6/1/2018 | +500 |
| 1 | 6/15/2018 | -300 |
| 1 | 7/1/2018 | +200 |
| 1 | 8/1/2018 | -400 |
| 1 | 12/15/2018 | +100 |
| 2 | 1/1/2018 | +10 |
| 2 | 6/1/2018 | +50 |
| 2 | 6/15/2018 | -30 |
| 2 | 7/1/2018 | +20 |
| 2 | 8/1/2018 | -40 |
| 2 | 12/15/2018 | +10 |
| 3 | 1/1/2018 | +100 |
| 3 | 6/1/2018 | +500 |
| 4 | 6/15/2018 | +300 |
| 4 | 7/1/2018 | +200 |
| 4 | 8/1/2018 | -400 |
| 4 | 12/15/2018 | +100 |
+--------------+------------+---------------+
You want a cumulative sum and then filtering:
select i.*
from (select i.*, sum(inventory_amt) over (partition by warehouse_id order by date) as inventory
from inventory i
) i
where inventory_amt > 750
Related
Bit of a hard one to explain, but basically I have table of orders, T1 for example:
---------------x---------x--------------x-----------------x
customer id | item | order date | recieved date |
---------------x---------x--------------x-----------------x
1 | Shoes | 01/12/2020 | 20/12/2020 |
1 | Bag | 22/12/2020 | 31/12/2020 |
1 | Bag | 05/01/2021 | 15/01/2021 |
1 | Hat | 07/04/2021 | 28/04/2021 |
2 | Bag | 04/06/2020 | 14/06/2020 |
3 | Shoes | 01/01/2022 | 11/01/2022 |
3 | Bag | 02/03/2022 | 23/03/2022 |
3 | Watch | 28/03/2022 | 05/08/2022 |
3 | Bag | 01/06/2022 | 13/06/2022 |
---------------x---------x--------------x-----------------x
Now say I want to find for every order of "Bags", what the last item the customer had received was and when (so as to look at which item they last received which may have influenced them to make the next purchase), so the resultant table would be something like:
---------------x---------x--------------x--------------------------x-----------------------x
customer id | item | order date | Previous Item Received | Prev Item Received Dt |
---------------x---------x--------------x--------------------------x-----------------------x
1 | Bag | 22/12/2020 | Shoes | 20/12/2020 |
1 | Bag | 05/01/2021 | Bag | 31/12/2020 |
2 | Bag | 04/06/2020 | NULL | NULL |
3 | Bag | 02/03/2022 | Shoes | 11/01/2022 |
3 | Bag | 01/06/2022 | Bag | 23/03/2022 |
---------------x---------x--------------x--------------------------x------------------------x
So if a customer orders an particular item, I want to find what their last received item was before that order was made, and what date it was received on.
I have a transaction table with both purchases and sales. Purchase datetime, quantity, unit cost as well as the corresponding Sales data.
I can separate the transactions with queries no problem there. What I need to do is determine which purchase order supplied the product sold and the difference in purchase and sale rate.
transDate | transType | Product | transQty | transRate
12/5/20 | purchase | pencils | 124 | $5.12
12/6/20 | sale | pencils | 32 | $6.12
12/7/20 | sale | pencils | 67 | $6.21
12/8/20 | purchase | pencils | 65 | $4.85
12/10/20 | sale | pencils | 44 | $6.32
12/11/20 | purchase | pencils | 14 | $6.11
The purchase on 12/5 covers the sales on 12/6, 12/7, and a portion of the sale in 12/10 with the purchase on 12/8 covering the remainder of 12/10.
Reorganized tables
tblPurchaseRecords
pID | transDate | Product | pQty | pTransRate | pRemaining
1 | 12/5/20 | pencils | 124 | $5.12 | 124
2 | 12/8/20 | pencils | 65 | $4.85 | 65
3 | 12/11/20 | pencils | 14 | $6.11 | 14
tblSaleRecords
sID | transDate | Product | sQty | sTransRate | sRemaining
1 | 12/6/20 | pencils | 32 | $6.12 | 32
2 | 12/7/20 | pencils | 67 | $6.21 | 67
3 | 12/10/20 | pencils | 44 | $6.32 | 44
New table
tblProfitLoss
pID | sID | plQty | plRate | plValue
tblProfitLoss is a many-to-many table with sID and pID forming the primary key.
plQty is the MIN(pRemaining, sRemaining). This value is subtracted from both pRemaining and sRemaining. One or both of the two values will be reduced to 0, advancing the respective index(es) by 1.
Resulting in this:
tblPurchaseRecords
pID | transDate | Product | pQty | pTransRate | pRemaining
1 | 12/5/20 | pencils | 124 | $5.12 | 0
+pID | sID | plQty | plRate | plValue
1 | 1 | 32 | $1.00 | $32.00
1 | 2 | 67 | $1.09 | $73.03
1 | 3 | 25 | $1.20 | $30
2 | 12/8/20 | pencils | 65 | $4.85 | 46
+pID | sID | plQty | plRate | plValue
2 | 3 | 19 | $1.47 | $27.93
3 | 12/11/20 | pencils | 14 | $6.11 | 14
tblSaleRecords
sID | transDate | Product | sQty | sTransRate | sRemaining
1 | 12/6/20 | pencils | 32 | $6.12 | 0
+pID | sID | plQty | plRate | plValue
1 | 1 | 32 | $1.00 | $32.00
2 | 12/7/20 | pencils | 67 | $6.21 | 0
+pID | sID | plQty | plRate | plValue
1 | 2 | 67 | $1.09 | $73.03
3 | 12/10/20 | pencils | 44 | $6.32 | 0
+pID | sID | plQty | plRate | plValue
1 | 3 | 25 | $1.20 | $30
2 | 3 | 19 | $1.47 | $27.93
I can do this with VBA but I was hoping to learn how to do it with SQL.
TABLE 2 : trip_delivery_sales_lines
+-------+---------------------+------------+----------+------------+-------------+--------+--+
| Sl no | Order_date | Partner_id | Route_id | Product_id | Product qty | amount | |
+-------+---------------------+------------+----------+------------+-------------+--------+--+
| 1 | 2020-08-01 04:25:35 | 34567 | 152 | 432 | 2 | 100 | |
| 2 | 2021-09-11 02:25:35 | 34572 | 130 | 312 | 4 | 150 | |
| 3 | 2020-05-10 04:25:35 | 34567 | 152 | 432 | 3 | 123 | |
| 4 | 2021-02-16 01:10:35 | 34572 | 130 | 432 | 5 | 123 | |
| 5 | 2020-02-19 01:10:35 | 34567 | 152 | 432 | 2 | 600 | |
| 6 | 2021-03-20 01:10:35 | 34569 | 152 | 123 | 1 | 123 | |
| 7 | 2021-04-23 01:10:35 | 34570 | 152 | 432 | 4 | 200 | |
| 8 | 2021-07-08 01:10:35 | 34567 | 152 | 432 | 3 | 32 | |
| 9 | 2019-06-28 01:10:35 | 34570 | 152 | 432 | 2 | 100 | |
| 10 | 2018-11-14 01:10:35 | 34570 | 152 | 432 | 5 | 20 | |
| | | | | | | | |
+-------+---------------------+------------+----------+------------+-------------+--------+--+
From Table 2 : we had to find partners in route=152 and find the sum of product_qty of the last 2 sale [can be selected by desc order_date]
. We can find its result in table 3.
34567 – Serial number [ 1,8]
34570 – Serial number [ 7,9]
34569 – Serial number [6]
TABLE 3 : RESULT OBTAINED FROM TABLE 1,2
+------------+-------+
| Partner_id | count |
+------------+-------+
| 34567 | 5 |
| 34569 | 1 |
| 34570 | 6 |
| | |
+------------+-------+
From table 4 we want to find the above partner_ids leaf count
TABLE 4 :coupon_leaf
+------------+-------+
| Partner_id | Leaf |
+------------+-------+
| 34567 | XYZ1 |
| 34569 | XYZ2 |
| 34569 | DDHC |
| 34567 | DVDV |
| 34570 | DVFDV |
| 34576 | FVFV |
| 34567 | FVV |
| | |
+------------+-------+
From that we can find result as:
34567 – 3
34569-2
34570 -1
TABLE 5: result obtained from TABLE 4
+------------+-------+
| Partner_id | count |
+------------+-------+
| 34567 | 3 |
| 34569 | 2 |
| 34570 | 1 |
| | |
+------------+-------+
Now we want compare table 3 and 5
If partner_id count [table 3] > partner_id count [table 4]
Print partner_id
I want a single query to do all these operation
distinct partner_id can be found by: fROM TABLE 1
SELECT DISTINCT partner_id
FROM trip_delivery_sales ts
WHERE ts.route_id='152'
GROUP BY ts.partner_id
This answers the original version of the problem.
You seem to want to compare totals after aggregating tables 2 and 3. I don't know what table1 is for. It doesn't seem to do anything.
So:
select *
from (select partner_id, sum(quantity) as sum_quantity
from (select tdsl.*,
row_number() over (partition by t2.partner_id order by order_date) as seqnum
from trip_delivery_sales_lines tdsl
) tdsl
where seqnum <= 2
group by tdsl.partner_id
) tdsl left join
(select cl.partner_id, count(*) as leaf_cnt
from coupon_leaf cl
group by cl.partner_id
) cl
on cl.partner_id = tdsl.partner_id
where leaf_cnt is null or sum_quantity > leaf_cnt
I am trying to give rank column of every group which repeating in every rows within the group of the original table but not the shape of after sum-up.
The formula i found in another site but it show an error :
https://intellipaat.com/community/9734/rank-categories-by-sum-power-bi
Table1
+-----------+------------+-------+
| product | date | sales |
+-----------+------------+-------+
| coffee | 11/03/2019 | 15 |
| coffee | 12/03/2019 | 10 |
| coffee | 13/03/2019 | 28 |
| coffee | 14/03/2019 | 1 |
| tea | 11/03/2019 | 5 |
| tea | 12/03/2019 | 2 |
| tea | 13/03/2019 | 6 |
| tea | 14/03/2019 | 7 |
| Chocolate | 11/03/2019 | 30 |
| Chocolate | 11/03/2019 | 4 |
| Chocolate | 11/03/2019 | 15 |
| Chocolate | 11/03/2019 | 10 |
+-----------+------------+-------+
The Goal
+-----------+------------+-------+-----+------+
| product | date | sales | sum | rank |
+-----------+------------+-------+-----+------+
| coffee | 11/03/2019 | 15 | 54 | 5 |
| coffee | 12/03/2019 | 10 | 54 | 5 |
| coffee | 13/03/2019 | 28 | 54 | 5 |
| coffee | 14/03/2019 | 1 | 54 | 5 |
| tea | 11/03/2019 | 5 | 20 | 9 |
| tea | 12/03/2019 | 2 | 20 | 9 |
| tea | 13/03/2019 | 6 | 20 | 9 |
| tea | 14/03/2019 | 7 | 20 | 9 |
| Chocolate | 11/03/2019 | 30 | 59 | 1 |
| Chocolate | 11/03/2019 | 4 | 59 | 1 |
| Chocolate | 11/03/2019 | 15 | 59 | 1 |
| Chocolate | 11/03/2019 | 10 | 59 | 1 |
+-----------+------------+-------+-----+------+
The script
sum =
SUMX(
FILTER(
Table1;
Table1[product] = EARLIER(Table1[product])
);
Table1[sales]
)
The Error :
EARLIER(Table1[product]) # Parameter is not correct type cannot find name 'product'
What's wrong with the script above ?
* not able to test this script:
rank = RANKX( ALL(Table1); Table1[sum]; ;; "Dense" )
before fixed the sum approach
The script is designed for a calculated column, not a measure. If you enter it as a measure, EARLIER has no "previous" row context to refer to, and gives you the error.
Create a measure:
Total Sales = SUM(Table1[sales])
This measure will be used to show sales.
Create another measure:
Sales by Product =
SUMX(
VALUES(Table1[product]);
CALCULATE([Total Sales]; ALL(Table1[date]))
)
This measure will show sales by product ignoring dates.
Third measure:
Sale Rank =
RANKX(
ALL(Table1[product]; Table1[date]);
[Sales by Product];;DESC;Dense)
Create a report with product and dates on a pivot, and drop all 3 measures into it. Result:
Tweak RANKX parameters to change the ranking mode, if necessary.
I have my dataset in the given format
It's a month level data along with salary for each month.
I need to calculate cumulative salary for each month end. How can I do this
+----------+-------+--------+---------------+
| Account | Month | Salary | Running Total |
+----------+-------+--------+---------------+
| a | 1 | 586 | 586 |
| a | 2 | 928 | 1514 |
| a | 3 | 726 | 2240 |
| a | 4 | 538 | 538 |
| b | 1 | 956 | 1494 |
| b | 3 | 667 | 2161 |
| b | 4 | 841 | 3002 |
| c | 1 | 826 | 826 |
| c | 2 | 558 | 1384 |
| c | 3 | 558 | 1972 |
| c | 4 | 735 | 2707 |
| c | 5 | 691 | 3398 |
| d | 1 | 670 | 670 |
| d | 4 | 838 | 1508 |
| d | 5 | 1000 | 2508 |
+----------+-------+--------+---------------+
I need to calculate running total column which is cumulative column. How can I do efficiently in SQL?
You can use SUM with ORDER BY clause inside the OVER clause:
SELECT Account, Month, Salary,
SUM(Salary) OVER (PARTITION BY Account ORDER BY Month) AS RunningTotal
FROM mytable