我正在使用Oracle 9i并且有两个重叠间隔的表:
CREATE TABLE slowdown (startdate DATE, enddate DATE, factor NUMBER);
CREATE TABLE products (prod VARCHAR2(10 BYTE) NOT NULL, STARTDATE DATE, ENDDATE DATE); -- In my usage this table is actually the result of a query and has many more rows
INSERT INTO slowdown(startdate, enddate, factor) VALUES (TO_DATE('09-SEP-2012 00:00:00', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('28-SEP-2012 00:00:00', 'DD-MON-YYYY HH24:MI:SS'), .70);
INSERT INTO slowdown(startdate, enddate, factor) VALUES (TO_DATE('23-MAR-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('28-MAR-2013 19:00:00', 'DD-MON-YYYY HH24:MI:SS'), 0);
INSERT INTO slowdown(startdate, enddate, factor) VALUES (TO_DATE('28-MAR-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('29-MAR-2013 07:00:00', 'DD-MON-YYYY HH24:MI:SS'), .25);
INSERT INTO products(prod, startdate, enddate) VALUES ('LOT001', TO_DATE('01-FEB-2012 13:30:00', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('05-FEB-2012 01:00:00', 'DD-MON-YYYY HH24:MI:SS'));
INSERT INTO products(prod, startdate, enddate) VALUES ('LOT001', TO_DATE('26-SEP-2012 00:00:00', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('30-SEP-2012 00:00:00', 'DD-MON-YYYY HH24:MI:SS'));
INSERT INTO products(prod, startdate, enddate) VALUES ('LOT123', TO_DATE('20-MAR-2013 11:13:45', 'DD-MON-YYYY HH24:MI:SS'), TO_DATE('28-MAR-2013 19:00:00', 'DD-MON-YYYY HH24:MI:SS'));
如您所见,products
中的时间间隔可能会与slowdown
中的零或更多重叠,反之亦然。间隔在同一个表格内可靠地不重叠。
对于xdays
和products
之间的每个重叠slowdown
,我需要将time_reduction
计算为xdays * factor
。
prod product_startdate product_enddate xdays fctr time_reduction
LOT001 01-FEB-2012 13:30 05-FEB-2012 01:00 0 NULL 0
LOT001 26-SEP-2012 00:00 30-SEP-2012 00:00 2 0.7 1.4
LOT123 20-MAR-2012 11:13 28-MAR-2012 19:00 0.5 0.25 0.125
是否有可以产生此结果的SQL语句?
答案 0 :(得分:2)
select
p.prod,
p.startdate as product_startdate,
p.enddate as product_enddate,
nvl(least(p.enddate, s.enddate) - greatest(p.startdate, s.startdate), 0) as xdays,
s.factor as fctr,
nvl(s.factor, 0) * nvl(least(p.enddate, s.enddate) - greatest(p.startdate, s.startdate), 0)
as time_reduction
from
products p
left join slowdown s
on least(p.enddate, s.enddate) - greatest(p.startdate, s.startdate) > 0
答案 1 :(得分:1)
select prod, startdate, enddate, factor, xdays,
xdays * nvl(factor, 1) time_reduction
from (select p.*, s.factor,
case
when s.startdate is null
then
0
else
least(p.enddate, s.enddate) - greatest(s.startdate, p.startdate)
end xdays
from products p, slowdown s
where s.startdate(+) <= p.enddate
and s.enddate(+) >= p.startdate);
答案 2 :(得分:0)
我会为每次计算编写PL / SQL函数,并将它们调用到我的select中以获得所需的结果。可能有一种方法可以在SQL中执行此操作,但它会变得有点难看。