我有两个单独的列,用于日期和时间,每个列都保存在varchar2
中我试图查询特定的时间范围:
即。 2017年1月1日至2017年1月31日 每天下午6点至6点之间
到目前为止,我做到了这一点:
选择*来自(选择a。*,TO_DATE(比尔特||'' || billtime,' YYYY / MM / DD HH24:Mi:SS') 作为Timex从billtable a billdate> =' 2017/01/01'和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') 按比例订购
我还能做些什么,或者我走错了路?
谢谢!
答案 0 :(得分:0)
假设您已经坚持使用数据模型(将日期和/或时间存储为字符串,或单独存储,这不是一个好主意)并且您对日期之前和之后的六个小时不感兴趣范围,您使用的格式至少可以让您简单地查询这些范围:
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;