I have a table like the one below and I want to get the manager who is associated to a class BETWEEN a start_date AND end_date
class_id | manager_id | start_date | end_date |
---|---|---|---|
1 | 999 | 2021-05-05 17:38:48 | 2021-05-05 17:39:38 |
2 | 999 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
3 | 999 | 2021-05-05 17:42:43 | 2021-05-05 17:47:45 |
4 | 999 | 2021-05-05 17:47:45 | NULL |
CREATE TABLE manager_class
(
class_id int
,manager_id int
,start_time timestamp(3)
,end_time timestamp(3)
)
INSERT INTO manager_class VALUES
(1,999,'2021-05-05 17:38:48'::timestamp(3), '2021-05-05 17:39:38'::timestamp(3))
,(2,999,'2021-05-05 17:39:38'::timestamp(3), '2021-05-05 17:42:43'::timestamp(3))
,(3,999,'2021-05-05 17:42:43'::timestamp(3), '2021-05-05 17:47:45'::timestamp(3))
,(4,999,'2021-05-05 17:47:45'::timestamp(3), NULL)
Use Cases IF _param_start_date = 2021-05-05 17:30:48 _param_end_date = 2021-05-05 17:42:43 THEN RESULT should be
class_id | start_date | end_date |
---|---|---|
1 | 2021-05-05 17:38:48 | 2021-05-05 17:39:38 |
2 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
IF _param_start_date = 2021-05-05 17:39:38 _param_end_date = 2021-05-05 17:42:43
class_id | start_date | end_date |
---|---|---|
2 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
IF _param_start_date = 2021-05-05 17:39:38 _param_end_date = 2021-05-05 17:55:43
class_id | start_date | end_date |
---|---|---|
2 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
3 | 2021-05-05 17:42:43 | 2021-05-05 17:47:45 |
4 | 2021-05-05 17:47:45 | NULL |
IF _param_start_date = '2021-05-05 17:47:45' _param_end_date = '2021-05-05 17:47:46'
class_id | start_date | end_date |
---|---|---|
4 | 2021-05-05 17:47:45 | NULL |
IF _param_start_date = '2021-05-05 17:39:38' _param_end_date = '2021-05-05 17:47:45'
class_id | start_date | end_date |
---|---|---|
2 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
3 | 2021-05-05 17:42:43 | 2021-05-05 17:47:45 |
4 | 2021-05-05 17:47:45 | NULL |
IF _param_start_date = '2021-05-05 17:39:38' _param_end_date = '2021-05-05 17:40:00'
class_id | start_date | end_date |
---|---|---|
2 | 2021-05-05 17:39:38 | 2021-05-05 17:42:43 |
What I have done so far:
SELECT class_id
,mc.start_time
,mc.end_time
FROM manager_class AS mc
WHERE mc.manager_id = 999
AND (
(
mc.start_time BETWEEN param_start_time AND param_end_time /* replace param_start_time and param_end_time */
AND (param_end_time >= mc.end_time)
)
OR (
param_start_time >= mc.start_time
AND (param_end_time <= mc.end_time OR mc.end_time IS NULL)
)
)
Overlapping intervals can be found this way. Not sure about NULL, this query considers mc.end_time is NULL
as an endless interval.
SELECT class_id
,mc.start_time
,mc.end_time
FROM manager_class AS mc
WHERE mc.manager_id = 999
AND mc.start_time <= param_end_time
AND (mc.end_time is NULL OR param_start_date <= mc.end_time)
If your parameters or table columns are allowed to contain null then your best bet seems to convert each to the appropriate range type and use the overlaps operator. Assuming all are defined as timestamps without time zone
then:
select class_id
, mc.start_time
, mc.end_time
from manager_class mc
where mc.manager_id = 999
and tsrange(parm_start_time, parm_end_time,'[)') &&
tsrange(mc,start_time,mc.end_time,'[)');
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.