Vous pouvez utiliser requêtes récursives pour satisfaire cela efficacement.
Ne vous inquiétez pas des types de données ne correspondant pas à votre table, le bit important est qu'ils commandent correctement.
/*
create table orders (pack_id int, qty int)
insert orders select 4, 500
create table stock (pack_id int, batchno int, qty int, mfgdate int)
insert stock select 4,1,200,1
insert stock select 4,3,1000,2
*/
-- target qty for a pack_id, or set these are SProc params
declare @packid int set @packid = 4
declare @qty int set @qty = 500
;with A as (
select *, rn=ROW_NUMBER() over (order by mfgdate, batchno)
from stock
where pack_id = @packid),
B as (
select pack_id, batchno, qty=case when qty>@qty then @qty else qty end, mfgdate, [email protected], rn
from A
where rn=1
union all
select A.pack_id, A.batchno, case when A.qty>to_go then to_go else A.qty end, A.mfgdate, @qty-A.qty, A.rn
from A
inner join B on A.rn=B.rn+1
where to_go > 0
)
select pack_id, batchno, qty, mfgdate
from B
order by mfgdate asc, batchno asc
Le premier CTE met en place les numéros de ligne afin que le 2e CTE peut passer par eux de façon séquentielle (vous ne pouvez pas utiliser TOP/agrégats dans la partie récursive du CTE); alors le 2ème collecte le stock jusqu'à ce que la quantité soit satisfaite
Donne une explication d'où proviennent les résultats de 200 et 300. – zerkms
300 xyz02 est nécessaire pour faire la quantité de 500 – RichardTheKiwi
quelle version de SQL Server? – RichardTheKiwi