简体   繁体   中英

Calculate dates between Start and end dates in SQL using case statement

I'm looking to calculate the number of days that overlap between to (DateTime) spans of time.

Logic behind the question is: A prisoner is serving a sentence from Orig bed start (beginning of his sentence) to Bed End Date (end of his sentence). During his sentence he took a leave of absence for whatever reason... idea is to calculate the numbers of days that specific prisoner took days off from his sentence as an example.

Making sure the leave start and end dates fall between the bed start and end days and then calculating the date difference and ignoring the rest.

Given this existing data:

ORIG_BED_START ORIG_BED_END LEAVE_START_DAT LEAVE_END_DATE LEAVE_DAYS
2022-10-19 09:21:00.000 2022-11-02 14:49:00.000 2022-10-28 00:00:00.000 2022-11-02 00:00:00.000 ??
2022-11-02 14:50:00.000 2022-11-16 13:19:00.000 2022-10-28 00:00:00.000 2022-11-02 00:00:00.000 ??
2022-12-19 10:17:00.000 2022-12-27 10:59:00.000 2022-12-19 00:00:00.000 2022-12-30 00:00:00.000 ??
2022-12-27 11:00:00.000 NULL 2022-12-19 00:00:00.000 2022-12-30 00:00:00.000 ??
2022-12-22 20:29:00.000 2022-12-29 17:48:00.000 2022-12-26 00:00:00.000 2022-12-30 00:00:00.000 ??
2022-12-29 17:49:00.000 2022-12-30 14:59:00.000 2022-12-26 00:00:00.000 2022-12-30 00:00:00.000 ??

I am expecting the result set to be:

ORIG_BED_START ORIG_BED_END LEAVE_START_DAT LEAVE_END_DATE LEAVE_DAYS
2022-10-19 09:21:00.000 2022-11-02 14:49:00.000 2022-10-28 00:00:00.000 2022-11-02 00:00:00.000 5
2022-11-02 14:50:00.000 2022-11-16 13:19:00.000 2022-10-28 00:00:00.000 2022-11-02 00:00:00.000 0
2022-12-19 10:17:00.000 2022-12-27 10:59:00.000 2022-12-19 00:00:00.000 2022-12-30 00:00:00.000 8
2022-12-27 11:00:00.000 NULL 2022-12-19 00:00:00.000 2022-12-30 00:00:00.000 3
2022-12-22 20:29:00.000 2022-12-29 17:48:00.000 2022-12-26 00:00:00.000 2022-12-30 00:00:00.000 4
2022-12-29 17:49:00.000 2022-12-30 14:59:00.000 2022-12-26 00:00:00.000 2022-12-30 00:00:00.000 0

This is the closest I have come

CASE 
    WHEN (CONVERT(DATE, LEAVE_START_DATE) >= CONVERT(DATE, ORIG_BED_START) AND 
          CONVERT(DATE, LEAVE_START_DATE) <= CONVERT(DATE, ORIG_BED_END)) 
         OR (CONVERT(DATE, LEAVE_END_DATE) >= CONVERT(DATE, ORIG_BED_END) AND CONVERT(DATE, LEAVE_END_DATE) <= CONVERT(DATE, ORIG_BED_END))
        THEN DATEDIFF(DAY, LEAVE_START_DATE, LEAVE_END_DATE)
        ELSE ''
END AS LEAVE_DAYS

The math to evaluate is MAX(0, MIN(orig_bed_end, leave_end_date) - MAX(orig_bed_start, leave_start_dat) ), in SQL that should give:

greatest(0, trunc( convert(date,least(coalesce(orig_bed_end,leave_end_date),leave_end_date)) - convert(date,greatest(orig_bed_start,leave_start_dat)))) 

Depending on where you will put the trunc - after or before calculating the difference - you may have slightly different results (+-1).

(quickly converted from ORACLE syntax, so may still need fixes to work in SQLServer)

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-2025 STACKOOM.COM