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

时间:2016-05-31 19:09:49

标签: oracle date odp.net between

我有一种情况需要每天23:00到次日01:00之间举办活动。 我的表格中有一个日期数据,如下所示:

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之间进行活动。

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

4 个答案:

答案 0 :(得分:1)

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 )
       )

答案 1 :(得分:1)

如果我收到问题,您希望将日期与日期分开处理。也就是说,2016年5月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会超出范围?< / p>

要使用DATE数据类型,您的范围跨越两个日期,因此您需要在时间输入值上添加日期,以便将00:23:11之类的时间视为YYYY-MM-DD 00:23 :11并使此日期/时间介于两个日期/时间之间(START_DATE和END_DATE。)

在你的例子中,2016-JUN-01 00:23:11可行,但2016年5月31日00:23:11不行。同样地,23:47:23,2016年5月31日23:47:23可行,但2016-JUN-01 23:47:23不会。

基本上,规则可以如下: 如果你想测试的时间是一小时&lt; 12(中午),追加END_DATE的日期,否则(小时&gt; = 12)追加START_DATE的日期,并将结果与​​START_DATE和END_DATE的日期/时间进行比较。

也许是这样的(我在这里使用查询来模拟您的开始/结束日期表):

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)

答案 2 :(得分:0)

您不需要将转换日期字段转换为字符,只需使用日期和BETWEEN clausule来完成您的选择:

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')

答案 3 :(得分:0)

这对我有用:

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