如何从 ORACLE 中 where 子句中的日期列中提取时间?

How to extract time from a date column in the where clause in ORACLE?

我想 select 具有特定时间间隔的行,但日期无关紧要。所以我需要一个函数 return 只是时间部分。我尝试使用:

to_char(mydate, 'HH12:MI:SS') between '00:00:00' and '08:00:00' 

但这似乎不起作用。有什么想法吗?

TO_CHAR(mydate, 'HH24:MI:SS')
WHERE mydate BETWEEN '00:00:00' AND '08:00:00'; 

通过一些示例数据,您可以看到使用 HH12 不一定会产生您期望的字符串:

alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';

-- CTE just for dummy data
with mytable (mydate) as (
            select cast(timestamp '2018-08-01 00:00:00' as date) from dual
  union all select cast(timestamp '2018-08-02 07:59:59' as date) from dual
  union all select cast(timestamp '2018-08-03 08:00:00' as date) from dual
  union all select cast(timestamp '2018-08-04 08:00:01' as date) from dual
  union all select cast(timestamp '2018-08-05 19:59:59' as date) from dual
  union all select cast(timestamp '2018-08-06 20:00:00' as date) from dual
  union all select cast(timestamp '2018-08-07 20:00:01' as date) from dual
)
-- actual query
select mydate,
  to_char(mydate, 'HH24:MI:SS') as time_24,
  to_char(mydate, 'HH12:MI:SS') as time_12
from mytable;

MYDATE              TIME_24  TIME_12 
------------------- -------- --------
2018-08-01 00:00:00 00:00:00 12:00:00
2018-08-02 07:59:59 07:59:59 07:59:59
2018-08-03 08:00:00 08:00:00 08:00:00
2018-08-04 08:00:01 08:00:01 08:00:01
2018-08-05 19:59:59 19:59:59 07:59:59
2018-08-06 20:00:00 20:00:00 08:00:00
2018-08-07 20:00:01 20:00:01 08:00:01

因此,当您尝试使用基于 HH12 的字符串进行过滤时,它会包含您不希望在上午 8 点到晚上 8 点之间看到的记录;并且还排除了午夜(因为那是“12:00:00”而不是“00:00:00”):

select mydate
from mytable
where to_char(mydate, 'HH12:MI:SS') between '00:00:00' and '08:00:00';

MYDATE             
-------------------
2018-08-02 07:59:59
2018-08-03 08:00:00
2018-08-05 19:59:59
2018-08-06 20:00:00

如果您使用 HH24 代替,那么您会得到

select mydate
from mytable
where to_char(mydate, 'HH24:MI:SS') between '00:00:00' and '08:00:00';

MYDATE             
-------------------
2018-08-01 00:00:00
2018-08-02 07:59:59
2018-08-03 08:00:00

另外,请注意 between 是包容性的,因此它会在 08:00:00 处获取记录。这可能不是您想要的 - 如果您将一天分成三个 8 小时的时间段,那么您不会多次包含那一秒的数据;所以你可以改用更明确的范围:

select mydate
from mytable
where to_char(mydate, 'HH24:MI:SS') >= '00:00:00'
and to_char(mydate, 'HH24:MI:SS') < '08:00:00';

MYDATE             
-------------------
2018-08-01 00:00:00
2018-08-02 07:59:59

那么你的第二班是:

where to_char(mydate, 'HH24:MI:SS') >= '08:00:00'
and to_char(mydate, 'HH24:MI:SS') < '16:00:00';

你的第三班是:

where to_char(mydate, 'HH24:MI:SS') >= '16:00:00';

或者如果您愿意,为了保持一致性:

where to_char(mydate, 'HH24:MI:SS') >= '16:00:00'
and to_char(mydate, 'HH24:MI:SS') < '24:00:00';

您永远无法将小时报告为 24,但因为它是一个字符串比较,虽然有点刺耳,但在这里并不重要。