我需要创建一个报告,按批号列出每个产品的可用数量。例如,我出售小部件A100。今天的日期是2014年11月2日,我手头有2个小部件A100(很多#1001和1002)。批次#1001的数量为100,而批次#1002的数量为200。我们有三个小工具A100的开放采购订单(PO#1003,1004和1005)。 PO#1003的数量为150,将于2014年2月20日到期,PO#1004的数量为200,将于2014年2月27日到期。最后,PO#1005的数量为250,并于2014年3月6日到期。因此,我们现有的现有数量为300,订购时为600。
假设我打开了四个销售订单(5001,5002,5003和5004)。销售订单5001为50,当前数量为50。销售订单5002为100,其数量为100。销售订单5003的数量为150,未提交,因为它不会在2014年2月24日之前发货。销售订单5004的数量为100,未提交,因为它不会在2014年3月3日之前发货。
现在,我需要根据上述和所有公开销售订单确定我可以出售的产品。
存储信息的表格如下(注意我已经简化了表格以便于沟通):
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
我需要一个sql语句,根据列出的表和记录创建所需的输出。任何建议将不胜感激!!!我宁愿不使用光标,但是如果不编写应用程序就无法找到解决方法。
答案 0 :(得分:0)
我使用Oracle完成了以下操作,并使用您的示例数据获得了您想要的结果。
如果您使用的是其他数据库,则可以模仿逻辑:
我确实做了一些假设,例如你的IN_INVENTORY表上的批次目前从未在你的PO_DTLS上成为DOC_NO。根据应用程序实际存储数据的方式,如果我做了任何错误的假设,请告诉我,逻辑可能会被编织。
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