简体   繁体   中英

SQL Query to find records that fall between a start and end date

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM