计算两个日期时间之间的7AM或7PM事件的数量

Tom*_*ell 5 sql oracle plsql oracle11g

是否有捷径可寻?完全介于两者之间,我的意思是不要将7am或7pm的日期时间计算为等于开始或结束时间.

我想这可以使用unix时间戳(以秒为单位)和一些代数来完成,但我无法弄明白.

我很高兴在PLSQL或纯SQL中使用某些东西.

例子:

start             end               num_7am_7pm_between_dates
2012-06-16 05:00  2012-06-16 08:00  1  
2012-06-16 16:00  2012-06-16 20:00  1
2012-06-16 05:00  2012-06-16 07:00  0
2012-06-16 07:00  2012-06-16 19:00  0
2012-06-16 08:00  2012-06-16 15:00  0
2012-06-16 05:00  2012-06-16 19:01  2
2012-06-16 05:00  2012-06-18 20:00  6 
Run Code Online (Sandbox Code Playgroud)

Rob*_*ler 3

我认为这可以进一步减少,但我没有可用的 Oracle 来完全测试此 Oracle SQL:

SELECT StartDate
     , EndDate
     , CASE WHEN TRUNC(EndDate) - TRUNC(StartDate) < 1
             AND TO_CHAR(EndDate, 'HH24') > 19
             AND TO_CHAR(StartDate, 'HH24') < 7
            THEN 2
            WHEN TRUNC(EndDate) - TRUNC(StartDate) < 1
             AND (TO_CHAR(EndDate, 'HH24') > 19
              OR  TO_CHAR(StartDate, 'HH24') < 7)
            THEN 1
            WHEN TRUNC(EndDate) - TRUNC(StartDate) > 0
             AND TO_CHAR(EndDate, 'HH24') > 19
             AND TO_CHAR(StartDate, 'HH24') < 7
            THEN 2 + ((TRUNC(EndDate) - TRUNC(StartDate)) * 2)
            WHEN TRUNC(EndDate) - TRUNC(StartDate) > 0
             AND TO_CHAR(EndDate, 'HH24') > 19
              OR TO_CHAR(StartDate, 'HH24') < 7
            THEN 1 + ((TRUNC(EndDate) - TRUNC(StartDate)) * 2)
            ELSE 0
       END
FROM MyTable;
Run Code Online (Sandbox Code Playgroud)

感谢 @ABCade 的 Fiddle,看起来我的 CASE 逻辑可以进一步压缩为:

SELECT SDate
     , EDate
     , CASE WHEN TO_CHAR(EDate, 'HH24') > 19
             AND TO_CHAR(SDate, 'HH24') < 7
            THEN 2 + ((TRUNC(EDate) - TRUNC(SDate)) * 2)
            WHEN TO_CHAR(EDate, 'HH24') > 19
              OR TO_CHAR(SDate, 'HH24') < 7
            THEN 1 + ((TRUNC(EDate) - TRUNC(SDate)) * 2)
            ELSE 0
       END AS MyCalc2
  FROM MyTable;
Run Code Online (Sandbox Code Playgroud)