select 在特定时间段内的日期范围之间

select between date range within speicific time period

我有两个单独的日期和时间列,每个列都保存在 varchar2 中

我正在尝试查询特定时间范围:

即1/1/2017 - 1/31/2017 每天下午 6 点到早上 6 点之间

到目前为止我这样做了:

select * 来自 (select a.*,TO_DATE(billdate||' '||billtime,'YYYY/MM/DD HH24:Mi:SS') 作为来自 billtable a 的 Timex where billdate >= '2017/01/01' and billdate <= '2017/01/31') 其中 timex>=to_date(''2017/01/01 18:00:00','YYYY/MM/DD HH24:Mi:SS') 和 timex<=to_date('2017/01/31 06:00:00','YYYY/MM/DD HH24:Mi:SS') 按账单日期排序

我还能做些什么,或者我走错路了吗?

谢谢!

假设您受困于现有的数据模型(将日期 and/or 次存储为字符串或单独存储不是一个好主意)并且您对前后六个小时不感兴趣日期范围,您使用的格式至少允许您相当简单地查询这些范围:

select a.*, to_date(billdate||' '||billtime,'YYYY/MM/DD HH24:Mi:SS') as timex
from billtable a
where billdate >= '2017/01/01'
and billdate <= '2017/01/31'
and (billtime <= '06:00:00' or billtime >= '18:00:00')
order by billdate, billtime;

CTE 中提供了一些示例数据:

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

with billtable (billdate, billtime) as (
  select '2017/01/01', '00:00:00' from dual
  union all select '2017/01/01', '06:00:00' from dual
  union all select '2017/01/01', '06:00:01' from dual
  union all select '2017/01/31', '17:59:59' from dual
  union all select '2017/01/31', '18:00:00' from dual
  union all select '2017/01/31', '23:59:59' from dual
)
select a.*, to_date(billdate||' '||billtime,'YYYY/MM/DD HH24:Mi:SS') as timex
from billtable a
where billdate >= '2017/01/01'
and billdate <= '2017/01/31'
and (billtime <= '06:00:00' or billtime >= '18:00:00')
order by billdate, billtime;

BILLDATE   BILLTIME TIMEX              
---------- -------- -------------------
2017/01/01 00:00:00 2017-01-01 00:00:00
2017/01/01 06:00:00 2017-01-01 06:00:00
2017/01/31 18:00:00 2017-01-31 18:00:00
2017/01/31 23:59:59 2017-01-31 23:59:59

如果您已经有一个日期,或者正在转换为一个日期——或者实际上是一个时间戳来完成这项工作——您可以这样做:

select billdate, billtime, cast(timex as date)
from (
  select a.*, to_timestamp(billdate||' '||billtime,'YYYY/MM/DD HH24:Mi:SS') as timex
  from billtable a
  where billdate >= '2017/01/01' and billdate <= '2017/01/31'
)
where extract(hour from timex) < 6
or (extract(hour from timex) = 6 and extract(minute from timex) = 0 and extract(second from timex) = 0)
or extract(hour from timex) >= 18
order by timex;