Home > Mobile >  Find total minutes without the overlapping times
Find total minutes without the overlapping times

Time:01-20

I was trying to find total number of minutes without the overlapping minutes. Below is sample table:

CREATE TABLE tim (starttime DATETIME, endtime DATETIME) 
INSERT INTO tim 
VALUES 
('2022-01-3 12:03:00.000',  '2022-01-3 12:20:00.000'),  
('2022-01-3 12:01:00.000',  '2022-01-3 12:06:00.000'),  
('2022-01-3 03:01:00.000',  '2022-01-3 03:06:00.000'),  
('2022-01-3 01:00:00.000',  '2022-01-3 01:26:00.000'),
('2022-01-3 01:03:00.000',  '2022-01-3 01:28:00.000'), 
('2022-01-3 01:05:00.000',  '2022-01-3 01:30:07.000')

When I run this line of query to select the time differences in the table, I get 17, 5, 5, 30 and 25 for the 5 consecutive rows (output is on the table below).

SELECT starttime, endtime, DATEDIFF(MINUTE,starttime, endtime) Diff FROM tim
starttime endtime diff
2022-01-3 12:03:00.000 2022-01-3 12:20:00.000 17
2022-01-3 12:01:00.000 2022-01-3 12:06:00.000 5
2022-01-3 03:01:00.000 2022-01-3 03:06:00.000 5
2022-01-3 01:00:00.000 2022-01-3 01:30:00.000 30
2022-01-3 01:03:00.000 2022-01-3 01:28:00.000 25
2022-01-3 01:05:00.000 2022-01-3 01:30:07.000 25

However, since the first two rows (row 1 and 2) and the last two rows (row 4 and 5) are overlapping, I would like to have the below records instead: Expected output:

starttime endtime diff
2022-01-3 01:00:00.000 2022-01-3 01:30:07.000 28
2022-01-3 03:01:00.000 2022-01-3 03:06:00.000 5
2022-01-3 12:01:00.000 2022-01-3 12:20:00.000 19

I was trying to apply LAG(starttime) over (order by starttime) and LEAD (starttime) over (order by starttime) , but they couldn't get it done for me consistently.

Any guide is appreciated.

CodePudding user response:

I think I have a lag/lead implementation that gives your desired results, does the following work for you?

with t as (
  select starttime,
    case when Lag(endtime) over (order by starttime) > starttime then 0 else 1 end UseStart,
    case when endtime < Lead(starttime) over(order by starttime) 
        then endtime 
      else Lead(endtime,1,endtime) over (order by starttime) 
    end endtime
 from tim
)
select starttime, endtime, DateDiff(minute,starttime, endtime) Diff 
from t
where UseStart=1

Working fiddle

CodePudding user response:

First, select every starttime you want. Use joins or subqueries to find if the starttime appears between the starttime and endtime in a different row or not. If it does, filter the current row out.

Second, find the best endtime for each starttime. Use a subquery to find all rows where the current row's starttime is between that starttime and endtime. Then select the latest (greatest) endtime.

  •  Tags:  
  • Related