This is PostgreSQL syntax, but it’s easy to translate to another SQL dialect
create table offdays(datum date);
insert into offdays(datum)
select to_date('2008-01-10','yyyy-MM-dd') UNION
select to_date('2008-01-11','yyyy-MM-dd') UNION
select to_date('2008-01-14','yyyy-MM-dd') UNION
select to_date('2008-01-20','yyyy-MM-dd') UNION
select to_date('2008-01-21','yyyy-MM-dd') UNION
select to_date('2008-01-26','yyyy-MM-dd');
create table leadtime (product_id integer , lead_time integer);
insert into leadtime(product_id,lead_time) values (9,5);
create table myorder (order_id integer,product_id integer, datum date);
insert into myorder(order_id,product_id,datum)
values (1,9,to_date('2008-01-09','yyyy-MM-dd'));
insert into myorder(order_id,product_id,datum)
values (2,9,to_date('2008-01-16','yyyy-MM-dd'));
insert into myorder(order_id,product_id,datum)
values (3,9,to_date('2008-01-23','yyyy-MM-dd'));
select order_id,min(finished_date)
FROM
(select mo.order_id,(mo.datum+lead_time+count(od2.*)::integer-1) as finished_date
from
myorder mo
join leadtime lt on (mo.product_id=lt.product_id)
join offdays od1 on (mo.datum<od1.datum)
left outer join offdays od2 on (mo.datum<od2.datum and od2.datum<od1.datum)
group by mo.order_id,mo.datum,lt.lead_time,od1.datum
having (mo.datum+lead_time+count(od2.*)::integer-1) < od1.datum) tmp
group by 1;
1 2008.01.16
2 2008.01.22
This will not return the result for orders that are completed after the last date in the offdays table (order number 3), so you should take care to insert offdays on time. It is assumed that orders executed do not start on weekends.
source
share