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
Multiply a factor by the overlaps between two tables with date ranges
Domanda
I am using Oracle 9i and have two tables with overlapping intervals:
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'));
As you can see, an interval in products
may overlap with zero or more in slowdown
or vice versa. Intervals reliably do not overlap within the same table.
For each overlap xdays
between products
and slowdown
, I need to calculate time_reduction
as 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
Is there an SQL statement which can produce this result?
Soluzione
Altri suggerimenti
you could do something like:
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);
fiddle: http://sqlfiddle.com/#!4/6983b/1
I'd write PL/SQL functions for each calculation and call them into my select to get the results you want. There might be a way to do this in SQL but it'll get a little ugly.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow