在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
我有一种情况,我需要在 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