Reputation: 1
I need to create a report that lists the quantity available per product by lot number. For example, I sell widget A100. Today's date is 2/11/2014 and I currently have 2 lots of widget A100 on hand (lot# 1001 and 1002). Lot# 1001 has a quantity of 100 on hand while lot# 1002 has a quantity of 200 on hand. We have three open purchase orders for widget A100 (PO# 1003, 1004, and 1005). PO#1003 is for a quantity of 150 and is due on 2/20/2014, PO# 1004 is for a quantity of 200 and is due on 2/27/2014. Finally, PO# 1005 is for a quantity of 250 and is due on 3/6/2014. So, we have a current quantity of 300 on hand and 600 on order.
Let's say I have four sales orders open (5001, 5002, 5003, and 5004). Sales Order 5001 is for 50 and has current quantity of 50 committed. Sales Order 5002 is for 100 and has quantity of 100 committed to it. Sales order 5003 is for a quantity of 150, not committed because it's not to ship until 2/24/2014. Sales Order 5004 is for a quantity of 100, not committed because it's not to ship until 3/3/2014.
Now, I need to figure out what I have available to sell based on the above and all open sales orders.
The tables that store the information are as follows (note I have simplified the tables for ease of communication):
IN_INVENTORY
ITEM_NO,
QTY_AVAILABLE
PO_DTLS
ITEM_NO,
DUE_DATE,
QTY_ORDERED
SO_DTLS
ITEM_NO,
SHIP_BY_DATE,
QTY_COMMITTED,
QTY_BACKORDERED
IN_INVENTORY
ITEM_NO LOT QTY
A100 1001 100
A100 1002 200
PO_DTLS
ITEM_NO DOC_NO DUE_DATE QTY
A100 1003 2/20/2014 150
A100 1004 2/27/2014 200
A100 1005 3/6/2014 250
SO_DTLS
ITEM_NO DOC_NO SHIP_BY_DATE QTY_COMMITTED QTY_BACKORDERED
A100 5001 2/14/2014 50 0
A100 5002 2/16/2014 100 0
A100 5003 2/24/2014 0 150
A100 5004 3/3/2014 0 100
My expected output would look as follows:
ITEM_NO LOT QTY_AVAILABLE AVAILABLE_DATE
A100 1002 50 2/11/2014
A100 1004 100 2/27/2014
A100 105 250 3/6/2014
I need a sql statement that creates the desired output based on the tables and records listed. Any suggestions would be greatly appreciated!!! I would rather not use a cursor but I can't figure out a way around not using one without writing an application to do it.
Upvotes: 0
Views: 2047
Reputation: 13248
I did the below using Oracle and get to your desired result with your example data.
If you're using a different database you may be able to mimic the logic:
I did make a few assumptions, such as the lots on your IN_INVENTORY table never currently being a DOC_NO on your PO_DTLS. Depending on how your application actually stores the data if I've made any bad assumptions let me know and the logic can probably be weaved in.
with sub1 as
(select x.item_no,
x.lot,
x.qty - y.going as qty_available,
to_date('02/11/2014', 'MM/DD/YYYY') as available_date
from in_inventory x
join (select item_no, sum(qty_committed) as going
from so_dtls
where qty_committed > 0
group by item_no) y
on x.item_no = y.item_no
where y.going < x.qty
order by 1, 2),
sub2 as
(select item_no, doc_no, runner, due_date
from ((select x.item_no,
x.doc_no,
x.qty,
y.going,
sum(x.qty - nvl(y.going, 0)) over(partition by x.item_no order by x.item_no, x.doc_no) as runner,
x.due_date
from po_dtls x
left join (select item_no, sum(qty_backordered) as going
from so_dtls
where qty_backordered > 0
group by item_no) y
on x.item_no = y.item_no
and x.doc_no = (select min(z.doc_no)
from po_dtls z
where z.item_no = x.item_no)
order by 1, 2))),
sub3 as
(select item_no, doc_no, qty, due_date
from ((select x.item_no,
x.doc_no,
x.qty,
y.going,
sum(x.qty - nvl(y.going, 0)) over(partition by x.item_no order by x.item_no, x.doc_no) as runner,
x.due_date
from po_dtls x
left join (select item_no, sum(qty_backordered) as going
from so_dtls
where qty_backordered > 0
group by item_no) y
on x.item_no = y.item_no
and x.doc_no > (select min(z.doc_no)
from po_dtls z
where z.item_no = x.item_no)
order by 1, 2)))
select *
from sub1
union
select *
from sub2
where sub2.doc_no = (select min(x.doc_no) from sub2 x where x.runner >= 0)
union all
select *
from sub3
where sub3.doc_no > (select min(x.doc_no) from sub2 x where x.runner >= 0)
order by item_no, lot
Upvotes: 0