Find duration on overlapping time segments in SQL - sql

I am working on building a query report where i have multiple types of segment with priority ranking on one table and second table with all types of segment with date, time etc. (as shown below) The duration for lower ranked segment during overlap should not be considered.
Please help me as I am unable to figure out query and get the duration of segment excluding the overlap based on ranking
table_Rank
Rank Code
1 x
2 y
3 z
4 a
5 b
6 c
7 d
8 r
9 f
Table_Segments
Code Date Start Time End Time Duration
a 18-Jul-15 17:30 17:45 0:15
c 18-Jul-15 18:00 19:00 1:00
y 18-Jul-15 18:45 19:00 0:15
a 18-Jul-15 20:15 20:20 0:05
b 18-Jul-15 23:45 1:00 1:15
z 19-Jul-15 0:30 1:15 0:45
f 19-Jul-15 2:00 3:00 1:00
Table With Ranks = Table_Rank
Table With Data = Table_Segments
What i am trying to achieves is, in an overlap situation overlap span should be considered for code with higher rank.
e.g.
Code Date Start Time End Time Duration
b 18-Jul-15 23:45 1:00 1:15
z 19-Jul-15 0:30 1:15 0:45
The actual duration output for b should 45 minutes as it has a lower rank compared to z and z should be 45 minutes

Related

How to get average value for each hourly increment that is split into 5 minute intervals

I have an AWS Redshift table that looks like this:
interval_date
interval_time
power
on_status
2022-05-01
00:00
2.65
Y
2022-05-01
00:05
3.92
Y
2022-05-01
00:10
2.05
Y
2022-05-01
00:15
1.85
Y
2022-05-01
00:20
5.92
Y
2022-05-01
00:25
7.52
Y
2022-05-01
00:30
9.84
Y
2022-05-01
00:35
6.84
N
2022-05-01
00:40
5.01
N
2022-05-01
00:45
4.70
N
2022-05-01
00:50
8.57
N
2022-05-01
00:55
1.94
N
2022-05-01
01:00
3.87
Y
The table continues with more timestamps going all the way until 11:55 PM for any given day up to the current day/time. I am trying to get the average value of power for each hourly interval (so the average for 12 AM should be the values from the previous day (4/30/2022) at 23:05 to current day (5/1/2022) at 00:00, 1 AM is 00:05 to 01:00, 2 AM is 01:05 to 02:00, etc) where the on_status equals Y.
I have a basic query that gets me the average for a whole day (for context, the interval_date would be parameterized).
SELECT AVG(power)
FROM table
WHERE on_status = 'Y'
AND interval_date = '2022-05-01';
I am unsure how to partition the interval_time column so that the values are averaged hourly. An idea of the final result I am looking for is:
interval_date
interval_time
power
on_status
2022-05-01
00:00
2.65
Y
2022-05-01
01:00
5.00
Y
2022-05-01
02:00
X
Y
2022-05-01
03:00
X
Y
You didn't specify the type for interval_time, so I'm assuming a string, you can parse it out with a case statement like this:
SELECT interval_date,
CASE WHEN SUBSTRING(interval_time,4,2)='00' THEN interval_time
WHEN SUBSTRING(interval_time,1,2)='23' THEN '00:00'
ELSE FORMAT(convert(int,SUBSTRING(interval_time,1,2))+1,'00')+':00'
END interval_time,
AVG(power)
FROM mytable
WHERE on_status = 'Y'
GROUP BY interval_date,
CASE WHEN SUBSTRING(interval_time,4,2)='00' THEN interval_time
WHEN SUBSTRING(interval_time,1,2)='23' THEN '00:00'
ELSE FORMAT(convert(int,SUBSTRING(interval_time,1,2))+1,'00')+':00'
END
Note that to get your target of 5.17, I had to comment out the on_status = 'Y' filter.
https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=b604e4fe6696465aac75676e69b92a47

Generate rows with time intervals between 2 dates in Oracle

I have table in which Sunday to Saturdy "Doctor Start" and "End Time" is given.
I want to create time slots of 15 minutes.
On the basis of that, the patient clicks on calendar datetime interval which shows slots that have already been booked.
The following example shows how to split time into slices of 15 minutes. It uses hierarchical query. A little bit of explanation:
line 2: trunc function, applied to a date value, returns "beginning" of that day (at midnight). Adding 15 / (24*60) adds 15 minutes (as there are 24 hours in a day and 60 minutes in an hour). Multiplying 15 by level works as a "loop", i.e. adds 15-by-15-by-15 ... minutes to previous value.
line 4: similar to line 2, but it makes sure that a day (24 hours * 60 minutes) is divided to 15-minutes parts
line 6: start time is trivial
line 7: end time just adds 15 minutes to start_time
line 9: return only time between 10 and 16 hours (you don't have patients at 02:15 AM, right?)
SQL> with fifteen as
2 (select trunc(sysdate) + (level * 15)/(24*60) c_time
3 from dual
4 connect by level <= (24*60) / 15
5 )
6 select to_char(c_time, 'hh24:mi') start_time,
7 to_char(c_time + 15 / (24 * 60), 'hh24:mi') end_time
8 from fifteen
9 where extract(hour from cast (c_time as timestamp)) between 10 and 15;
START_TIME END_TIME
---------- ----------
10:00 10:15
10:15 10:30
10:30 10:45
10:45 11:00
11:00 11:15
11:15 11:30
11:30 11:45
11:45 12:00
12:00 12:15
12:15 12:30
12:30 12:45
12:45 13:00
13:00 13:15
13:15 13:30
13:30 13:45
13:45 14:00
14:00 14:15
14:15 14:30
14:30 14:45
14:45 15:00
15:00 15:15
15:15 15:30
15:30 15:45
15:45 16:00
24 rows selected.
SQL>

Split a time duration into time segments

I have an incident start time and end time e.g Sr=tart time of 15/01/2018 11:30 and end time of 16/01/2018 02:40 in an excel table.
How can I split this time range into different time segments. The segments are:-
06:00 - 11:59, 12:00 - 14:59, 15:00 - 17:59, 18:00 - 22:59, 23:00 - 05:59
For 06:00 - 11:59 I would expect 0.50 as this is 30 mins.
For 12:00 - 14:59 I would expect 3.0 for 3 hours.
For 15:00 - 17:59 I would expect 3.0 for 3 hours again.
For 18:00 - 22:59 this should be 5hrs
and for 23:00 - 02:40 should be 3.67 hrs.
What formula would I need to achieve this?
For the example you give with the layout as shown below this formula should work:
=MIN($D3-F$1,MIN(F$2-F$1,IF($C3<F$2,F$2-$C3+SUM($E3:E3),)))
The formula in C3 is:
=24*(MOD(A3,1))
and in D3:
=24*(MOD(B3,1)+INT(B3>INT(A3)))

How to count the records per half hour from a period (datetimefrom and datetimeto) field?

I have a table which looks like you can see below:
Id Date ScheduledTimeFrom ScheduledTimeTo ActualTimeFrom ActualTimeTo
1 2013-01-01 1899-12-30 07:00:00 1899-12-30 18:00:00 1899-12-30 07:23:00 1899-12-30 17:15:00
I need to calculate per half hour how many records exists, the output should be like:
Time Actual Count:
7:00 4
7:30 4
8:00 4
8:30 4
9:00 4
9:30 5
10:00 5
10:30 6
11:00 7
11:30 8
12:00 8
12:30 8
13:00 8
13:30 8
14:00 8
14:30 8
15:00 7
15:30 7
16:00 7
16:30 6
17:00 5
17:30 4
18:00 4
I already tried to make a helper table which should hold the times per halfhour. I have joined this helpertable with the table that contains the data and after that I tried to use a group by function but it was not working.
My query was like:
Create table period (timefrom datetime, timeto datetime)
insert into period
select '1899-12-30 07:00:00.000', '1899-12-30 07:30:00.000'
Union all
select '1899-12-30 07:30:00.000', '1899-12-30 08:00:00.000'
select *
from period p left join table1 t on t.ActualTimeFrom < p.timeto and t.ActualTimeTo >=p.timefrom
Grouping this give me no desired result....
Anyone an idea how to come to the result?
P.s. I am using sql server 2005.
After snooping around and testing it on my side, looks like this date function could be the answer:
DATEADD(mi,DATEDIFF(mi,0,YOUR_DATE_COLUMN)/30*30,0)

SQL How Many Employees Are Working, Group By Hour

I have a table, a timetable, with check-in and check-out times of the employees:
ID Date Check-in Check out
1 1-1-2011 11:00 18:00
2 1-1-2011 11:00 19:00
3 1-1-2011 16:00 18:30
4 1-1-2011 17:00 20:00
Now I want to know how many employees are working, every (half) hour.
The result I want to see:
Hour Count
11 2
12 2
13 2
14 2
15 2
16 3
17 3
18 2,5
19 1
Every 'Hour' you must read as 'till the next full hour', ex. 11 -> 11:00 - 12:00
Any ideas?
Build an additional table, called Hours, containing the following data:
h
00:00
00:30
01:00
...
23:30
then, run
Select h as 'hour' ,count(ID) as 'count' from timetable,hours where [Check_in]<=h and h<=[Check_out] group by h