Мне нужно обрабатывать перекрывающиеся даты, но если дата окончания равна нулю, то следует предположить, что процесс не остановился - PullRequest
1 голос
/ 18 апреля 2019

У меня есть дата начала и дата окончания процесса из двух разных источников. Эти два источника будут объединены, и даты должны быть обработаны в случае конфликтов

Набор данных1

 P_startDate    P_EndDate  
 1-Jan-07        1-Jun-15

Набор данных2

P_Start Date    P_End Date  
1-Mar-15          1-Jan-17  
2-Jan-17           Null

Объединенный набор данных / Ожидаемый набор данных

 | Process Start Date | Process End Date  |
 | 1-Jan-07           |  1-Mar-15         |
 | 1-Mar-15           |  1-Jan-17         |
 | 2-Jan-17           |  Null             |

Я создал код, но он дает мне результат, когда условие нулевого (без даты окончания) не учитываетсяи мой выход выходит как

| Process Start Date |  Process End Date  |
| 1-Jan-07           |  1-Mar-15          |
| 1-Mar-15           |  1-Jan-17          |
| 1-Jan-17           |  2-Jan-17          |

Я следовал инструкциям отсюда
http://www.schemamania.org/sql/#overlapping.dates

with D (ID, bound) as (  
    select   ID   
       , case T when 's' then StartDate else EndDate end as bound  
    from  (  
    select ID, StartDate, EndDate from so.A   
    UNION  
    select ID, StartDate, EndDate from so.B  
    ) as U  
    cross join (select 's' as T union select 'e') as T  
)  
select P.*
from (  
    select s.ID, s.bound as StartDate, min(e.bound) as EndDate    
    from D as s join D as e   
    on s.ID = e.ID   
    and s.bound < e.bound  
    group by s.ID, s.bound  
 ) as P  
 left join so.A as a  
 on  P.ID = a.ID   
 and a.StartDate <= P.StartDate and P.EndDate <= a.EndDate  
 left join so.B as b  
 on  P.ID = b.ID   
 and b.StartDate <= P.StartDate and P.EndDate <= b.EndDate  
 order by P.ID, P.StartDate, P.EndDate  

1 Ответ

1 голос
/ 18 апреля 2019

Это больше похоже на проблему интервала перекрытия слиянием.Вот одно решение, которое поддерживает текущий счетчик начала и конца:

CREATE TABLE ds1 (P_STARTDATE DATE, P_ENDDATE DATE);
CREATE TABLE ds2 (P_STARTDATE DATE, P_ENDDATE DATE);

INSERT INTO ds1 VALUES
('2007-01-01', '2015-06-01');

INSERT INTO ds2 VALUES
('2015-03-01', '2017-01-01'),
('2017-01-02', NULL);

WITH cte1(d, v) AS (
    SELECT P_startDate, +1 FROM ds1 UNION ALL
    SELECT P_EndDate,   -1 FROM ds1 UNION ALL
    SELECT P_startDate, +1 FROM ds2 UNION ALL
    SELECT P_EndDate,   -1 FROM ds2
), cte2(d, c) AS (
    SELECT d, SUM(SUM(v)) OVER (ORDER BY CASE WHEN d IS NULL THEN 2 ELSE 1 END, d)
    FROM cte1
    GROUP BY d
), cte3(d, c, f) AS (
    SELECT d, c, CASE WHEN LAG(c) OVER (ORDER BY CASE WHEN d IS NULL THEN 2 ELSE 1 END, d) > 0 THEN 0 ELSE 1 END
    FROM cte2
), cte4(d, c, g) AS (
    SELECT d, c, SUM(f) OVER (ORDER BY CASE WHEN d IS NULL THEN 2 ELSE 1 END, d)
    FROM cte3
)
SELECT MIN(d) AS FromDate, CASE WHEN COUNT(d) = COUNT(*) THEN MAX(d) END AS ToDate
FROM cte4
GROUP BY g;

Результат:

FromDate               ToDate
01/01/2007 00:00:00    01/01/2017 00:00:00
02/01/2017 00:00:00    02/01/2017 00:00:00
...