MySQL get list of start time and end time conflict - mysql

Need help for MySQL query for retrieving record of class schedule that is conflict in the given time.
Ex.
SchedID StartTime EndTime
1 09:00:00 13:00:00
2 08:30:00 10:00:00
3 11:00:00 15:00:00
4 07:30:00 08:30:00
5 11:30:00 13:00:00
I would like to retrieve the list that is conflict in this given time
Start Time = 09:00:00
End Time = 11:00:00
The record will yield following result:
SchedID StartTime EndTime
1 09:00:00 13:00:00
2 08:30:00 10:00:00
3 11:00:00 15:00:00
Thank you.

Try this
SELECT DISTINCT a.schedid, a.starttime, a.endtime
FROM
tbl_name a, tbl_name b
WHERE ((b.starttime > a.starttime AND b.starttime < a.endtime)
OR (b.endtime > a.starttime AND b.endtime < a.endtime))
ORDER BY schedid

i just found my answer here Determine Whether Two Date Ranges Overlap
Heres my query:
SELECT * FROM tableName WHERE (start_time < givenEndTime)
AND (end_time > givenStartTime);
This works perfectly fine for me.

Related

Find out given time is available from different time slot using SQL

slot
start_time
end_time
t1
06:00:00
09:00:00
t2
09:00:00
11:00:00
t3
11:00:00
12:00:00
This is sample table.
Given start_time and end_time is 08:30:00 - 09:15:00
How to write sql query for find slot available or not.
Already try below code is not working
SELECT
*
FROM
TABLE
WHERE ((start_time <= '08:30:00'
AND end_time >= '09:15:00')
or((start_time < '08:30:00'
AND end_time > '08:30:00')
and(start_time < '09:15:00'
AND end_time > '09:15:00')))
Excepted Result
slot
start_time
end_time
t1
06:00:00
09:00:00
t2
09:00:00
11:00:00
scenario 2
SAMPLE TABLE
slot
start_time
end_time
t1
06:00:00
09:00:00
t2
10:00:00
11:00:00
t3
11:00:00
12:00:00
If table like this expected result will get null . Why second table t1 start from 6 - 9 and next slot t2 start from 10 - 11. our given time is 8.30 to 9.15.
You can write something like this:
SELECT *
FROM my_table
WHERE start_time <= '08:30:00' AND end_time >= '09:15:00'

Mysql Find free time periods between appointments and within working periods

Table "Working periods":
id
started_at
ended_at
1
2022-06-09 08:00:00
2022-06-09 12:00:00
2
2022-06-09 13:00:00
2022-06-09 16:00:00
Table "Appointments":
id
started_at
ended_at
1
2022-06-09 08:00:00
2022-06-09 09:00:00
2
2022-06-09 09:00:00
2022-06-09 10:00:00
3
2022-06-09 15:00:00
2022-06-09 16:00:00
I need to find free periods of time within "Working periods" and excluding "Appointments" using only one MySQL query (statement). So, the query should result in the following table:
id
started_at
ended_at
1
2022-06-09 10:00:00
2022-06-09 12:00:00
2
2022-06-09 13:00:00
2022-06-09 15:00:00
I have tried the following query, which does almost what I need, but is tied to only one "Working period" defined with 2 hardcoded variables:
set #timeSlider='2022-06-09 08:00:00';
set #timeMaximum='2022-06-09 15:00:00';
select if (d.name = 'free', #timeSlider, a.started_at) as started_at,
if (d.name = 'free', a.started_at, #timeSlider := a.ended_at) as ended_at,
d.name as `status`
from (select 1 as place, 'free' as name union select 2 as place, 'busy' as name) as d
inner join appointments a
having started_at < ended_at AND `status` = 'free'
union select #timeSlider as started_at, #timeMaximum as ended_at, 'free' as `status`
from (select 1) as d
where #timeSlider < #timeMaximum
order by started_at, ended_at;
Is there a way to set the variables for each "Working period" separately and fit the entire query in 1 SQL statement? Or maybe there is another way to solve the problem?

How to get the data only on working hours

Is there a way to select or query the data only on working hours?
id
description
datetime
1
Alarm Activated
2022-01-02 14:00:00
2
Alarm Deactivated
2022-01-02 15:00:00
3
Alarm Activated
2022-01-03 18:00:00
..
Alarm Activated
2022-01-31 11:00:00
I'd like to get the number of the alarm activated on or during working hours from mon-fri 8am to 5pm.
I tried to use the between date but no luck.
SELECT * -- if you need to count them only - use SELECT COUNT(*)
FROM datatable
WHERE WEEKDAY(`datetime`) < 5 -- test weekday
AND TIME(`datetime`) BETWEEN '08:00:00' AND '17:00:00'; -- test hours
Here we use the following tests:
weekday < 6 (Saturday) = Monday to Friday
hour more than 7 (from 08:00:00)
hour less than 17 (to 16:59:59)
create table alarms(
id int,
description varchar(100),
date_time datetime);
insert into alarms values
(1,'Alarm Activated',
'2022-01-02 14:00:00'),
(2,'Alarm Deactivated',
'2022-01-02 15:00:00'),
(3,'Alarm Activated',
'2022-01-03 18:00:00'),
(4,'Alarm Activated',
'2022-01-31 11:00:00');
select *
from alarms
where weekday(date_time) < 6
and 7 < hour(date_time) < 17;
id | description | date_time
-: | :-------------- | :------------------
3 | Alarm Activated | 2022-01-03 18:00:00
4 | Alarm Activated | 2022-01-31 11:00:00
db<>fiddle here

Time difference without considering times between 0am ~ 4am. MySQL

MySQL version 8.0
I want to calculate time difference between two datetime column.
And get rows where duration >= 12:00:00.
which I would normally do:
select id
, start_time
, end_time
, timediff(end_time, start_time) as duration
from table;
which I would get something like this:
id start_time end_time duration
0 1 2020-06-01 01:00:00 2020-06-01 14:00:00 13:00:00
1 2 2020-06-01 01:00:00 2020-06-01 18:00:00 17:00:00
2 3 2020-06-01 19:00:00 2020-06-02 10:00:00 15:00:00
3 4 2020-06-02 04:00:00 2020-06-02 16:00:00 12:00:00
For duration column I don't want times between 00:00:00 ~ 04:00:00 to be added towards the duration. So for the first row duration = 10:00:00 since 01:00:00~14:00:00 = 10:00:00, ignoring times between 00:00:00 ~ 04:00:00
same for second row we substract 3 hours from duration.
so my desired output would be:
id start_time end_time duration
0 1 2020-06-01 01:00:00 2020-06-01 14:00:00 10:00:00
1 2 2020-06-01 01:00:00 2020-06-01 18:00:00 14:00:00
2 3 2020-06-01 19:00:00 2020-06-02 10:00:00 11:00:00
3 4 2020-06-02 04:00:00 2020-06-02 16:00:00 12:00:00
There are lots of rows where times include minutes and seconds too.
Thanks in advance!
I've grabbed all rows where duration >= 12:00:00.
Then separated data into 4 regions depending on their start_time.
a_region = 00~04
b_region = 04~12
c_region = 12~16
d_region = 16~24
For a_region I've subtracted 04:00:00 - start_time which is time we should compensate to duration in a_region.
compensation = 04:00:00 - start_time
compensated_time = duration - compensation.
For b_region it needs no compensation if it has passed 00~04 it means it already passed duration = 12:00:00.
For c_region,
compensation = 16:00:00 - start_time
compensated_time = duration - compensation
For d_region since we've grabbed duration >= 12:00:00
it will pass all of 00~04 therefore
compensated_time = duration - 04:00:00.
I solved it using Python but above is the logic I've used.
One option uses greatest():
select id
, start_time
, end_time
, timediff(
greatest(,
end_time,
date_format(end_time, '%Y-%m-%d 04:00:00')
),
greatest(
start_time,
date_format(start_time, '%Y-%m-%d 04:00:00')
)
) as duration
from table;

MariaDb/MySQL sliding sum over 24 hours

My table have fields that represent starting and ending working period as datetime.
I need to find related entries that match a total of 14hours min over a sliding period of 24 hours.
I think window function will (maybe) save me, but MariadDB (i use) doesn't implement yet Range time intervals in window function.
here is some example data:
id starting_hour ending_hour
-- ------------------- -------------------
1 2018-09-02 06:00:00 2018-09-02 08:30:00
2 2018-09-03 08:30:00 2018-09-03 10:00:00
4 2018-09-03 11:00:00 2018-09-03 15:00:00
5 2018-09-02 15:30:00 2018-09-02 16:00:00
6 2018-09-02 16:15:00 2018-09-02 17:00:00
7 2018-09-20 00:00:00 2018-09-20 08:00:00
8 2018-09-19 10:00:00 2018-09-19 12:00:00
9 2018-09-19 12:00:00 2018-09-19 16:00:00
10 2018-10-08 12:00:00 2018-10-08 14:00:00
11 2018-10-29 09:00:00 2018-10-29 10:00:00
So how to find rows where in a 24 hours window their sum a more or equal to 14 hours.
thanks
Edit:
SELECT
id,
starting_hour,
ending_hour,
TIMEDIFF (ending_hour, starting_hour) AS duree,
(
SELECT SUM(TIMEDIFF(LEAST(ending_hour, DATE_ADD(a.starting_hour, INTERVAL 24 HOUR)), starting_hour)) / 10000
FROM `table` b
WHERE b.starting_hour BETWEEN a.starting_hour AND DATE_ADD(a.starting_hour, INTERVAL 24 HOUR)
) AS duration
FROM
`table` a
HAVING duration >= 14
ORDER BY starting_hour ASC
;
This returns Id 8 but i want the whole period. (eg: Id 8, Id 9 and Id 7)
EDIT2:
The expected results are ranges of working time where they are in a window of 24 hours and where their sum are more or equal to 14 hours.
EDIT 3:
In fact under MySQL 8 this seems to work.
SELECT * FROM (
SELECT
*,
SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(hs.`ending_hour`, hs.`starting_hour`))) OVER (ORDER BY hs.starting_hour RANGE BETWEEN INTERVAL '12' HOUR PRECEDING AND INTERVAL '12' HOUR following)) AS tot
FROM
table hs
WHERE hs.`starting_hour` > DATE_SUB(NOW(), INTERVAL 50 DAY) AND hs.`ending_hour` <= NOW()
ORDER BY hs.`starting_hour` ASC
) t1
HAVING tot >= '14:00:00'
;
Is there a way to do it under MariaDB 10.2 without window function ? Or without window range function ?