我有一种情况需要每天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已经结束而失败。所以,我不能使用日期查询之间的正常。
答案 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