Thank for your checking this one out. I need a SQL Server query that will return a list by date of the expected quantity of items on hand after upcoming sales along with the quantity of items that will expire if unsold.
The inventory is stored in lots that have an expiration date. In this example, we have 2 lots. Lot_id(50)
has qty 20 items that will expire on 2022-12-13 if they are not sold, and Lot_id(52)
has qty 40 items that will expire on 2022-12-14 if they are not sold.
Currently, there are 3 orders: Qty 10 on 2022-12-11, Qty 20 on 2022-12-12, and Qty 25 on 2022-12-13.
Given two tables, inventory
and sales
.Inventory
:
| lot_id | item_id | quantity_on_hand | lot_expiration_date |
| ------------ | ------------ | ------------ | ------------ |
| 50 | 1 | 20 | 2022-12-13 |
| 52 | 1 | 40 | 2022-12-14 |Sales
:
| order_id | item_id | order_date | order_qty |
| ------------ | ------------ | ------------ | ------------ |
| 100 | 1 | 2022-12-11 | 10 |
| 101 | 1 | 2022-12-12 | 20 |
| 102 | 1 | 2022-12-13 | 25 |
Exhibit A - Daily Journal of sales for item_id = 1
| Date | Expiration_Qty | Order_Qty | Lot_id_50 | Lot_id_52 | Unexpired_Qty_On_Hand | Expired_Qty_On_Hand |
| ------------ | ------------ | ------------ | ------------ | ------------ | ------------ | ------------ |
| 2022-12-10 | | 0 | 20 | 40 | 60 | 0 |
| 2022-12-11 | | 10 | 10 | 40 | 50 | 0 |
| 2022-12-12 | | 20 | 0 | 30 | 30 | 0 |
| 2022-12-13 | 20 | 25 | 0 | 5 | 5 | 0 |
| 2022-12-14 | 40 | 0 | 0 | 0 | 0 | 5 |
Exhibit B - Daily Journal explanation by day
2022-12-10 There is a total of 60 qty on hand (total unexpired from all lots), no orders, and no expirations
2022-12-11 There is a sales order for 10 qty, and no expirations
2022-12-12 There is a sales order for 20 qty, and no expirations
2022-12-13 There is a sales order for 25 qty, and 20 qty from Lot_id_50 would have expired had they not sold.
2022-12-14 There are no sales orders, and the remaining qty (5) in Lot_id_52 expires
The desired result with show the item_id, along with expected unexpired Qty on hand and the expected qty that will expire by date.
| Date | item_id | Unexpired_Qty_On_Hand | Expired_Qty_On_Hand |
| ------------ | ------------ | ------------ | ------------ |
| 2022-12-10 | 1 | 60 | 0 |
| 2022-12-11 | 1 | 50 | 0 |
| 2022-12-12 | 1 | 30 | 0 |
| 2022-12-13 | 1 | 5 | 0 |
| 2022-12-14 | 1 | 0 | 5 |
Code:
-- SQL to create tables and populate
CREATE TABLE `sales`
(
`order_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`order_date` date NOT NULL,
`order_quantity` int(11) NOT NULL
);
INSERT INTO `sales` (`order_id`, `item_id`, `order_date`, `order_quantity`)
VALUES (100, 1, '2022-12-11', 10),
(101, 1, '2022-12-12', 20),
(102, 1, '2022-12-13', 25);
CREATE TABLE `inventory`
(
`lot_id` int(11) NOT NULL,
`item_id` int(11) NOT NULL,
`quantity_on_hand` int(11) NOT NULL,
`lot_expiration_date` date NOT NULL
);
INSERT INTO `inventory` (`lot_id`, `item_id`, `quantity_on_hand`, `lot_expiration_date`)
VALUES (50, 1, 20, '2022-12-13'),
(52, 1, 40, '2022-12-14');
1条答案
按热度按时间of1yzvn41#
If the business never sells expired items to customers, which means a sales order is always taken if there's sufficient
unexpired_qty_on_hand
.Then,
Step 1. Get a list of dates based on given report date ranges
cte_report_date
Step 2. Calculate
unexpired_qty_on_hand
andexpired_qty_on_hand
byreport_date
,lot_id
,item_id
incte_inventory_by_date_lot
Step 3. Aggregate the above to
report_date
anditem_id
level incte_inventory_by_date
Step 4. Calculate
sales_quantity
andtotal_sales_quantity
(cumulative sales qty) byorder_date
anditem_id
incte_sales_by_date
Step 5. Generate all combination of (
report_date
,item_id
) for reportingStep 6. From the above left join to
cte_sales_by_date
to get sales by report dateStep 7. Join and compare
inventory
andsales
to calculate[unexpired | expired]_qty_on_hand
byreport_date
xitem_id
Outcome:
The query may not cover all use cases outside of the provided sample data but hopefully it gets you started.