question

sirishb avatar image
sirishb asked

SQL Find adjacent schedule time and combine them

Hello,

Say we have a table like below:

Please note the start and end time and if they start or end at the same time then they need to be combined. Thanks.

EMP ID Schedule 1 start time Schedule 1 End Time Schedule 2 start time Schedule 2 End Time

1 2020-03-01 7:00am 2020-03-01 10:00am 2020-03-01 10:00am 2020-03-01 08:00pm

1 2020-03-04 6:00am 2020-03-04 4:00pm 2020-03-04 5:00pm 2020-03-04 10:00pm

1 2020-03-04 10:00pm 2020-03-05 06:00am 2020-03-07 06:00am 2020-03-07 10:00am


How do we combine these schedules without a cursor/loop so that it becomes

EMP ID Schedule 1 start time Schedule 1 End Time Schedule 2 start time Schedule 2 End Time

1 2020-03-01 7:00am 2020-03-01 08:00pm 2020-03-04 6:00am 2020-03-04 4:00pm

1 2020-03-04 5:00pm 2020-03-05 06:00am 2020-03-07 06:00am 2020-03-07 10:00am

time
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

1 Answer

·
sirishb avatar image
sirishb answered

Here is the solution.

Use lag and lad to flag and delete the records.


id emp_id schedule

1 1 2020-03-01 07:00:00.000

2 1 2020-03-01 09:00:00.000

3 1 2020-03-01 20:00:00.000

4 1 2020-03-04 06:00:00.000

5 1 2020-03-04 16:00:00.000

6 1 2020-03-04 17:00:00.000

7 1 2020-03-04 22:00:00.000

8 1 2020-03-04 22:00:00.000

9 1 2020-03-05 06:00:00.000

10 1 2020-03-07 06:00:00.000

11 1 2020-03-07 10:00:00.000

12 2 2020-03-04 22:00:00.000

13 2 2020-03-05 06:00:00.000

14 2 2020-03-07 06:00:00.000

15 2 2020-03-07 11:00:00.000

16 2 2020-03-05 22:00:00.000

17 2 2020-03-06 06:00:00.000

18 2 2020-03-07 06:00:00.000

19 2 2020-03-07 10:00:00.000

20 1 2020-03-01 09:00:00.000

21 3 2020-03-01 07:00:00.000

22 3 2020-03-01 09:00:00.000

23 3 2020-03-01 09:00:00.000

24 3 2020-03-01 11:00:00.000

25 3 2020-03-01 11:00:00.000

26 3 2020-03-01 14:00:00.000

27 4 2020-03-01 07:00:00.000

28 4 2020-03-01 15:00:00.000



--DROP TABLE #tmp

SELECT

/* This is for test */

s.emp_id, s.schedule, LAG(schedule) OVER (PARTITION BY emp_id ORDER BY schedule) AS previous_schedule,

/* This is the logic */

CASE

WHEN schedule = LAG(schedule) OVER (PARTITION BY emp_id ORDER BY schedule)

THEN 1

WHEN schedule = LEAD(schedule) OVER (PARTITION BY emp_id ORDER BY schedule)

THEN 1

ELSE 0 END AS match,

ROW_NUMBER() OVER ( PARTITION BY emp_id ORDER BY schedule ASC) AS seq

INTO #tmp

FROM

[dbo].[test_schedule] s

ORDER BY emp_id ASC, schedule ASC



--DROP TABLE #tmp_1

SELECT * INTO #tmp_1 FROM #tmp

WHERE match=0

ORDER BY 1,2 ASC


--TEST

--SELECT * FROM #tmp_1


SELECT

a.emp_id,

a.schedule AS Schedule_Start_Time,

b.schedule AS Schedule_End_Time


FROM #tmp_1 a

INNER JOIN

#tmp_1 b

ON a.emp_id = b.emp_id

AND a.seq = b.seq+1

ORDER BY 1,2 ASC

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.