在Oracle中查找两个字段之间的当前时间

Find current time between two fields in Oracle

我有一种情况,我需要在 23:00 小时到第二天 01:00 小时之间每天提出一个事件。 我的 table 有一个日期数据,如下所示:

Start date          | EndDate
31-05-2016 23:00:00 | 01-06-2016 01:00:00

数据库已经设计成这样,应用程序已经上线。现在,我尝试使用 BETWEEN 语句获取数据,但是,由于 ENDDate 是第二天早上,所以我需要的任何东西都不起作用。

谁能告诉我如何正确提取这些数据。

我的ORACLE查询

 SELECT COUNT(*) INTO P_OUTPUT FROM MAINTENANCE_LOG WHERE      
 NVL(RECCURING_TYPE,'O')='D' AND ACTIVE_STATUS='Y' AND
 TO_CHAR(SYSDATE,'HH24MISS') BETWEEN TO_CHAR(START_DATE,'HH24MISS') AND TO_CHAR(END_DATE,'HH24MISS');

我再次尝试将其转换为日期,但它也不适用于 EndDate。

更新: 在我的要求中,我只需要检查当前时间是否在开始日期或结束日期时间之间。我每天都需要 运行 这个查询,它应该在每天的 23:00 和 1:00 之间执行 activity。

注意:如果我在 2015 年 5 月 31 日 运行 查询 Sysdate between startdate and enddate,我将得到 true/false。但是,如果我在第二天晚上 运行 我只会得到 false,因为 EndDate 已经结束。所以,我不能使用正常的日期查询。

您不需要将日期字段转换为字符,只需使用日期和 BETWEEN 条款即可完成您的 select:

SELECT COUNT(*) INTO P_OUTPUT 
FROM MAINTENANCE_LOG 
WHERE      
   NVL(RECCURING_TYPE,'O')='D' AND 
   ACTIVE_STATUS='Y' AND
   SYSDATE BETWEEN START_DATE AND END_DATE;

无论如何,在您的问题中...您可以添加 YYYYMMDD...但是,如果您使用的是日期字段,请不要这样做。

TO_CHAR(SYSDATE,   'YYYYMMDDHH24MISS') BETWEEN 
TO_CHAR(START_DATE,'YYYYMMDDHH24MISS') AND 
TO_CHAR(END_DATE,  'YYYYMMDDHH24MISS')
SELECT COUNT(*)
INTO   P_OUTPUT
FROM   MAINTENANCE_LOG
WHERE  RECCURING_TYPE = 'D'
AND    ACTIVE_STATUS  = 'Y'
AND    ( SYSDATE - TRUNC(SYSDATE) BETWEEN START_DATE - TRUNC( START_DATE )
                                      AND END_DATE   - TRUNC( START_DATE )
       OR
         SYSDATE - TRUNC(SYSDATE) BETWEEN START_DATE - TRUNC( END_DATE )
                                      AND END_DATE   - TRUNC( END_DATE )
       )

如果我明白了这个问题,您想将时间与日期分开处理。也就是说,2016-MAY-31 23:00:00 应该被视为只是 23:00:00 和 2016-JUN-01 01:00:00 应该被视为只是 01:00:00 并且将这两次视为一个范围?因此,如果我正在查看 23:47:43 或 00:23:11 的时间,两者都会被视为在范围内,但像 22:56:34 和 01:34:52 这样的时间会超出范围吗?

要使用 DATE 数据类型,您的范围跨越两个日期,因此您需要将日期放在时间输入值上,这样像 00:23:11 这样的时间将被视为 YYYY-MM-DD 00:23:11 并使这个 date/time 落在你的两个 date/time 之间(START_DATE 和 END_DATE。)

在您的示例中,2016-JUN-01 00:23:11 会起作用,但 2016-MAY-31 00:23:11 不会。同样,对于 23:47:23,2016-MAY-31 23:47:23 会起作用,但 2016-JUN-01 23:47:23 不会。

基本上,规则可以如下: 如果您要测试的时间有一个小时 < 12(中午),则附加 END_DATE 中的日期,否则(小时 >= 12)附加 START_DATE 中的日期并将结果与date/times 在 START_DATE 和 END_DATE.

可能是这样的(我在这里模拟你的 start/end 日期 table 与查询):

WITH test_data AS 
(SELECT '00:23:11' as time_char
   FROM dual
 UNION ALL
 SELECT '23:47:23' as time_char
   FROM dual
 UNION ALL 
 SELECT '22:56:34' as time_char
 FROM dual
 UNION ALL
 SELECT '01:34:52' as time_char
   FROM dual
 UNION ALL
 SELECT '12:34:52' as time_char
   FROM dual
 UNION ALL
 SELECT '23:00:00' as time_char
   FROM dual
 UNION ALL
 SELECT '01:00:00' as time_char
   FROM dual
 UNION ALL
 SELECT '22:59:59' as time_char
   FROM dual
 UNION ALL
 SELECT '01:0:01' as time_char
   FROM dual
)
SELECT test_data.time_char, start_end_table.*
FROM (SELECT TO_DATE('2016-MAY-31 23:00:00', 'YYYY-MON-DD HH24:MI:SS') as start_date
           , TO_DATE('2016-JUN-01 01:00:00', 'YYYY-MON-DD HH24:MI:SS') as end_date
        FROM dual
     ) start_end_table
     FULL OUTER JOIN
     test_data
     ON  
     CASE WHEN TO_NUMBER(SUBSTR(test_data.time_char, 1, 2)) < 12 
           THEN TO_DATE(TO_CHAR(start_end_table.end_date, 'YYYYMMDD')||test_data.time_char, 'YYYYMMDDHH24:MI:SS')
           ELSE TO_DATE(TO_CHAR(start_end_table.start_date, 'YYYYMMDD')||test_data.time_char, 'YYYYMMDDHH24:MI:SS')
      END 
      BETWEEN start_end_table.start_date AND start_end_table.end_date

TIME_CHAR   START_DATE              END_DATE
00:23:11    2016-MAY-31 23:00:00    2016-JUN-01 01:00:00
23:47:23    2016-MAY-31 23:00:00    2016-JUN-01 01:00:00
23:00:00    2016-MAY-31 23:00:00    2016-JUN-01 01:00:00
01:00:00    2016-MAY-31 23:00:00    2016-JUN-01 01:00:00
01:34:52          (null)                   (null)
01:0:01           (null)                   (null)
22:59:59          (null)                   (null)
22:56:34          (null)                   (null)
12:34:52          (null)                   (null)

这对我有用:

SELECT COUNT(*)
INTO   P_OUTPUT
FROM   MAINTENANCE_LOG
WHERE  RECCURING_TYPE = 'D'
AND    ACTIVE_STATUS  = 'Y'
AND  SYSDATE BETWEEN YEAR_FROM and YEAR_TO