I want to achieve similar function that is available in Time Period Library for .NET, but in SQL.
First, I have a table with several rows with an Start Date and an End Date, and I want to consolidate them together like this:
Then with that result and another coming from a different table, I want to find out the intersection between the two of them, like this but only 2 inputs (find the periods that are present in both):
Once I have the intersection is just summing up the time on it.
Here I provide a SQL Fiddle with the expected output with an example:
Sample data preparation
CREATE TABLE TableToCombine
([IdDoc] int IDENTITY(1,1), [IdEmployee] int, [StartDate] datetime, [EndDate] datetime)
;
INSERT INTO TableToCombine
(IdEmployee, StartDate, EndDate)
VALUES
(1, '2018-01-01 06:00:00', '2018-01-01 14:00:00'),
(2, '2018-01-01 11:00:00', '2018-01-01 19:00:00'),
(3, '2018-01-01 20:00:00', '2018-01-02 03:00:00'),
(1, '2018-01-02 06:00:00', '2018-01-02 14:00:00'),
(2, '2018-01-02 11:00:00', '2018-01-02 19:00:00')
;
CREATE TABLE TableToIntersect
([IdDoc] int IDENTITY(1,1), [OrderId] int, [StartDate] datetime, [EndDate] datetime)
;
INSERT INTO TableToIntersect
(OrderId, StartDate, EndDate)
VALUES
(1, '2018-01-01 09:00:00', '2018-01-02 12:00:00')
;
Query:
with ExpectedCombineOutput as (
select
grp, StartDate = min(StartDate), EndDate = max(EndDate)
from (
select
*, sum(iif(cd between StartDate and EndDate, 0, 1))over(order by StartDate) grp
from (
select
*, lag(EndDate) over (order by IdDoc) cd
from
TableToCombine
) t
) t
group by grp
)
select
a.grp, StartDate = iif(a.StartDate < b.StartDate, b.StartDate, a.StartDate)
, EndDate = iif(a.EndDate < b.EndDate, a.EndDate, b.EndDate)
from
ExpectedCombineOutput a
join TableToIntersect b on a.StartDate <= b.EndDate and a.EndDate >= b.StartDate
Intersecting time intervals are combined in CTE. And then joined with your intersectTable to find overlapping periods. Two periods overlap if a.StartDate < b.EndDate and a.EndDate > b.StartDate