Sql server 2012 如何为此场景编写Sql查询,用于订单、批次库存管理Sql Server

Sql server 2012 如何为此场景编写Sql查询,用于订单、批次库存管理Sql Server,sql-server-2012,Sql Server 2012,场景:如果订单数量小于或等于第一个可用批次数量,则显示第一个批次;如果订单数量大于第一个可用批次数量,则显示该产品的两个批次 桌子看起来像这样 订单表 批处理表 我试过下面的方法 SELECT pm.ProductID as [Product ID], pm.ProductCode as [Product Code], pm.BarCode, pm.ProductName as [Product Name], m.Pack, SUM(od.OrderQt

场景:如果订单数量小于或等于第一个可用批次数量,则显示第一个批次;如果订单数量大于第一个可用批次数量,则显示该产品的两个批次

桌子看起来像这样

订单表

批处理表

我试过下面的方法

SELECT  
    pm.ProductID as [Product ID], pm.ProductCode as [Product Code],
    pm.BarCode, pm.ProductName as [Product Name], 
    m.Pack,  
    SUM(od.OrderQty) as [Order Qty],
    SUM(od.OrderQty) * m.Pack, 
    0 as DeliveryNoteQty, 
    SUM(od.ConvertedQty) as [Order Qty(Units)],   
    CONVERT(varchar(20), sm.ExpiryDate, 105) AS [Expiry Date], 
    sm.BatchID, sm.QuantityInHand as gcount 
FROM 
    OrderFormHeader oh 
INNER JOIN 
    OrderFormDetail od ON oh.OrderFormID = od.OrderFormID  
INNER JOIN 
    ProductMaster pm ON pm.ProductID = od.ProductID 
INNER JOIN 
    ProductMultipleUnits m ON pm.ProductID = m.ProductID 
                           AND od.UnitID = m.UnitID  
CROSS APPLY 
    (SELECT TOP 1 
         sm1.QuantityInHand, sm1.BatchID, sm1.ExpiryDate 
     FROM 
         StockMaster sm1 
     WHERE 
         sm1.ProductID = pm.ProductID 
     ORDER BY 
         sm1.ExpiryDate ASC) sm  
WHERE 
    pm.ActiveFlag = 1 
    AND m.ActiveFlag = 1 
    AND oh.OrderFormID = 89 
GROUP BY 
    pm.BarCode, pm.ProductID, pm.ProductCode, pm.ProductName, m.UOI, 
    m.Pack, sm.QuantityInHand, sm.BatchID, sm.ExpiryDate 
ORDER BY
    pm.ProductCode, sm.ExpiryDate ASC 

对于订单和批处理表,您可以编写类似于下面的表

select 1 'id',1 'pid',100 'qty' into #order
insert into #order
select 2,2,50


select 1 'bid',1 'pid', 50 'qtyinhand', GETDATE() 'expirtydate' into #batch

insert into #batch
select 2,1,25, GETDATE()

insert into #batch
select 3,1,25, GETDATE()

insert into #batch
select 4,2,125, GETDATE()

insert into #batch
select 5,2,23, GETDATE()

insert into #batch
select 5,2,23, GETDATE()

go

with order_cte(pid,batchid)
as
(
    select pid,min(bid) from #batch
    group by pid
)

select ord.pid,bat.bid,bat.qtyinhand into #result from order_cte cte
inner join
#order ord on cte.pid = ord.pid
inner join
#batch bat on bat.bid = cte.batchid
where ord.qty <= bat.qtyinhand

insert into #result
select ord.pid,bat.bid,bat.qtyinhand from #order ord
inner join
#batch bat on ord.pid = bat.pid
where ord.pid not in (select pid from #result)


select * from #result
SELECT  
    pm.ProductID as [Product ID], pm.ProductCode as [Product Code],
    pm.BarCode, pm.ProductName as [Product Name], 
    m.Pack,  
    SUM(od.OrderQty) as [Order Qty],
    SUM(od.OrderQty) * m.Pack, 
    0 as DeliveryNoteQty, 
    SUM(od.ConvertedQty) as [Order Qty(Units)],   
    CONVERT(varchar(20), sm.ExpiryDate, 105) AS [Expiry Date], 
    sm.BatchID, sm.QuantityInHand as gcount 
FROM 
    OrderFormHeader oh 
INNER JOIN 
    OrderFormDetail od ON oh.OrderFormID = od.OrderFormID  
INNER JOIN 
    ProductMaster pm ON pm.ProductID = od.ProductID 
INNER JOIN 
    ProductMultipleUnits m ON pm.ProductID = m.ProductID 
                           AND od.UnitID = m.UnitID  
CROSS APPLY 
    (SELECT TOP 1 
         sm1.QuantityInHand, sm1.BatchID, sm1.ExpiryDate 
     FROM 
         StockMaster sm1 
     WHERE 
         sm1.ProductID = pm.ProductID 
     ORDER BY 
         sm1.ExpiryDate ASC) sm  
WHERE 
    pm.ActiveFlag = 1 
    AND m.ActiveFlag = 1 
    AND oh.OrderFormID = 89 
GROUP BY 
    pm.BarCode, pm.ProductID, pm.ProductCode, pm.ProductName, m.UOI, 
    m.Pack, sm.QuantityInHand, sm.BatchID, sm.ExpiryDate 
ORDER BY
    pm.ProductCode, sm.ExpiryDate ASC 
select 1 'id',1 'pid',100 'qty' into #order
insert into #order
select 2,2,50


select 1 'bid',1 'pid', 50 'qtyinhand', GETDATE() 'expirtydate' into #batch

insert into #batch
select 2,1,25, GETDATE()

insert into #batch
select 3,1,25, GETDATE()

insert into #batch
select 4,2,125, GETDATE()

insert into #batch
select 5,2,23, GETDATE()

insert into #batch
select 5,2,23, GETDATE()

go

with order_cte(pid,batchid)
as
(
    select pid,min(bid) from #batch
    group by pid
)

select ord.pid,bat.bid,bat.qtyinhand into #result from order_cte cte
inner join
#order ord on cte.pid = ord.pid
inner join
#batch bat on bat.bid = cte.batchid
where ord.qty <= bat.qtyinhand

insert into #result
select ord.pid,bat.bid,bat.qtyinhand from #order ord
inner join
#batch bat on ord.pid = bat.pid
where ord.pid not in (select pid from #result)


select * from #result