Getting available date intervals with overlapping busy times - sql

I'm trying to get available date intervals from a predefined available dates and busy times.
Table of possible dates (slots)
ID
SLOT_BEG
SLOT_END
1
11/10/2021 09:00:00
11/10/2021 09:15:00
2
11/10/2021 09:15:00
11/10/2021 09:30:00
3
11/10/2021 09:30:00
11/10/2021 09:45:00
4
11/10/2021 09:45:00
11/10/2021 10:00:00
Busy times
ID
MEET_BEG
MEET_END
1
11/10/2021 09:00:00
11/10/2021 09:15:00
2
11/10/2021 09:32:24
11/10/2021 09:46:00
Desired result:
ID
SLOT_BEG
SLOT_END
2
11/10/2021 09:15:00
11/10/2021 09:30:00
db<>fiddle here
I'm unable to find a way to handle the overlapping cases like meet ID 2 - it needs to block 2 slots because the starting date is not aligned.
Any help is appreciated.

Use not exists with a subquery testing if the invervals do overlap
select * from T_TMP_SLOT s
where not exists (
select null from T_TMP_MEET m
where not (s.SLOT_END <= m.MEET_BEG or m.MEET_END <= s.SLOT_BEG)
);
ID SLOT_BEG SLOT_END
---------- ------------------- -------------------
2 11.10.2021 09:15:00 11.10.2021 09:30:00
Note that the intervals do not overlap if the slot end before (or equal) begin of meeting OR if the meeting ends before (or eq) slot begin.
So make a negation of this predicate to get overlapping meetings and check with not exists that such meetings do not exists..

Related

How to find entry that is between two dates?

I have a table as:
Id start_timestamp end_timestamp
1 2021-07-12 03:00:00 2021-07-13 11:58:05
2 2021-07-13 04:00:00 2021-07-13 05:00:00
3 2021-07-13 04:00:00 2021-07-13 09:00:00
4 2021-07-13 04:00:00 NULL
5 2020-04-10 04:00:00 2020-04-10 04:01:00
....
I want to find all records that fall between two specific timestamps? Basically I'm looking to understand what process ran during a high pick time of the day (it doesn't matter if they have 1 sec in the window or hours.. just occurrence in the window is enough)
So if the timestamps are 2021-07-13 00:00:00 to 2021-07-13 04:30:00
The query will return
1
2
3
4
How can I do that with SQL? (Preferably Presto)
This is the overlapping range problem. You may use:
SELECT *
FROM yourTable
WHERE
(end_timestamp > '2021-07-13 00:00:00' OR end_timestamp IS NULL) AND
(start_timestamp < '2021-07-13 04:30:00' OR start_timestamp IS NULL);
My answer assumes that a missing start/end timestamp value in the table logically means that this value should not be considered. This seems to be the logic you want here.

SQL Server datetime ranges between records

What would be the best way to get datetime ranges between records in SQL Server? I think it would be easiest to explain with an example.
I have the following data - these records start and end datetime ranges would never overlap:
ID
Start
End
1
1/27/2021 06:00:00
1/27/2021 09:00:00
2
1/27/2021 10:00:00
1/27/2021 14:00:00
3
1/27/2021 21:00:00
1/28/2021 04:00:00
4
1/28/2021 06:00:00
1/28/2021 09:00:00
I need to get the date time range between records. So the resulting SQL query would return the following result set (ID doesn't matter):
ID
Start
End
1
1/27/2021 09:00:00
1/27/2021 10:00:00
2
1/27/2021 14:00:00
1/27/2021 21:00:00
3
1/28/2021 04:00:00
1/28/2021 06:00:00
Thanks for any help in advance.
Use lead():
select t.*
from (select id, end as start, lead(start) over (order by start) as end
from t
) t
where end is not null;
Note: end is a lousy name for a column, given that it is a SQL keyword. I assume it is for illustrative purposes only.
Here is a SQL Fiddle.

Google Bigquery - Create time series of number of active records

I'm trying to create a timeseries in google bigquery SQL. My data is a series of time ranges covering the period of activity for that record. Here is an example:
Start End
2020-11-01 21:04:00 UTC 2020-11-02 07:15:00 UTC
2020-11-01 21:45:00 UTC 2020-11-02 04:00:00 UTC
2020-11-01 22:00:00 UTC 2020-11-02 09:48:00 UTC
2020-11-01 22:00:00 UTC 2020-11-02 06:00:00 UTC
I wish to create a new table to total the number of active records within a 15 minute block. "21:00:00" would for example be 21:00 to 21:14.59. My desired output for the above would be:
Period Active_Records
2020-11-01 21:00:00 1
2020-11-01 21:15:00 1
2020-11-01 21:30:00 1
2020-11-01 21:45:00 2
2020-11-01 22:00:00 4
2020-11-01 22:15:00 4
etc until the end of the last active range.
I would also like to be able to generate this on the fly by querying a date range and having it return every 15 minute block in the range and how many active records there was in that period.
Any assistance would be greatly appreciated.
Below is for BigQuery Standard SQL
#standardSQL
select ts as period, count(1) as Active_Records
from unnest((
select generate_timestamp_array(timestamp_trunc(min(start), hour), max(`end`), interval 15 minute)
from `project.dataset.table`
)) ts
join `project.dataset.table`
on not (`end` < ts or start > timestamp_add(ts, interval 15 * 60 - 1 second))
group by ts
if to apply to sample data from your question - output is

SQL SELECT Difference between two days greater than 1 day

I have table T1
ID SCHEDULESTART SCHEDULEFINISH
1 2018-05-12 14:00:00 2018-05-14 11:00:00
2 2018-05-30 14:00:00 2018-06-01 11:00:00
3 2018-02-28 14:00:00 2018-03-02 11:00:00
4 2018-02-28 14:00:00 2018-03-01 11:00:00
5 2018-05-30 14:00:00 2018-05-31 11:00:00
I want to select all rows where difference in days (it's not important difference in hours) is greater than 1 day.
If SCHEDULESTART or SCHEDULEFINISH are on the same day or SCHEDULEFINISH is on next day then these rows should NOT be selected.
So the result should return rows with IDs: 1 2 3
because first row have difference in two days, second row (1st June is 2 days after 30th May ) and 3rd row (2nd March is 2 days after 28 February).
Is this possible somehow?
I know the function DAY but this will return only day number in that one month!!!
I must beging my query with
SELECT ID FROM T1 WHERE ...
Thanks in advance
In DB2, this should work:
select t1.*
from t1
where date(schedulestart) < date(schedulefinish) - 1 day;

SQL Server : get start time and end time with in the multiple night shift

How can I get the Start and End time of this list? I can add date to this time and can get by min and max but you can see row 3 have next day shift but it will come under same date because it is night shift
I have added normal day shift employee also get the logic right
EmployeeId ShiftDate ShiftStartTime ShiftEndTime
-----------------------------------------------------
20040 2017-11-01 21:00:00 23:00:00
20040 2017-11-01 23:00:00 00:30:00
20040 2017-11-01 00:30:00 06:00:00
20124 2017-11-01 09:00:00 16:30:00
20124 2017-11-01 16:30:00 22:00:00
20124 2017-11-01 22:00:00 22:30:00
I need it like below:
EmployeeId ShiftDate ShiftStartTime ShiftEndTime
----------------------------------------------------
20040 2017-11-01 21:00:00 06:00:00
20124 2017-11-01 09:00:00 22:30:00
In a commercial environment we solved this by attaching a FLAG to each shift. The Flag would indicate the 'Reporting Date' of the Shift...The Flag would have have a value of 1 if the 'Reporting / Administrative date' was the 'next' day. 0 for the same day. -1 for the previous day (which we never used...depends on your scenario)
I modified your table to show a possible SHIFTS table, which should also have a NAME column I guess (like Morning, Afternoon, Day, Night shift etc)
ReportFlag ShiftStartTime ShiftEndTime
1 21:00:00 23:00:00
1 23:00:00 00:30:00
0 00:30:00 06:00:00
0 09:00:00 16:30:00
0 16:30:00 22:00:00
1 22:00:00 22:30:00
Notice how I added 1 - to say that 'this shift' is actually considered to be on the 'next' day.
Then you can use your flag value 0,1 to add to DATE functions in your queries too