这是 PostgreSQL 语法,但应该很容易翻译成其他 SQL 方言
--Sample data
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'));
--Query
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;
--Results :
1 2008.01.16
2 2008.01.22
对于将在 offdays 表中的最后一个日期之后完成的订单(订单号 3),这不会返回结果,因此您必须注意按时插入 offdays。假设订单不会在 offdays 开始。