我有4条用户输入:startDate
,endDate
,startTime
,endTime
。
数据库中的日期和时间设置与我之前使用的任何设置不同。日期是自1900年12月31日以来的天数。所以整数。例如,2015年10月16日,将表示为41927。
时间是ISO格式 - 没有小数,所以也是整数。因此08:00:00将是80000. 19:00:00将是190000.它基本上是hhmmss - 但有时你只有一个h。
我正在尝试将日期和时间过滤到范围内。有一天,我只是看着时间,这很好用:
SELECT * FROM database WHERE day = 41927 AND time > startTime and time < endTime
如果您严格关注日子,它也会有效:
SELECT * FROM database WHERE day > startDate AND day < endDate
当您需要在两个日期之间找到两次日期之类的项目时会出现问题,因为它会过滤掉每天两次之间的任何日期。我知道有一种方法可以创建一个时间戳,但是我很难用两个整数把它放在查询中。
我有哪些选择来解决这个问题?
答案 0 :(得分:2)
您可以使用简单的算术:
select date('1900-12-31') + col days
但是,我怀疑实际日期开始日期是1899-12-31。这是Excel使用的日期(因此第1天是1900-01-01)。
编辑:
哎呀,撇开秒。一种方法是:select timestamp(date('1900-12-31') + coldays days) +
(floor(coltime / 10000) * 60*60 +
mod(floor(coltime / 100)) * 60
mod(coltime, 100)
) seconds
答案 1 :(得分:2)
虽然你有一个有效的答案(来自你的评论)......
select * from mytable
where CURRENT_TIMESTAMP
< timestamp(date('1900-12-31') + coldays days)
+ (floor(coltime / 10000) * 60*60
+ mod(floor(coltime / 100),100) * 60 mod(coltime, 100) )
您可能会发现它执行得不好,因为WHERE
子句中列的函数用法限制了标准索引的可用性。充其量,您将获得完整的索引扫描,更糟糕的是,您将获得全表扫描。
两个选项
1)操作系统的最新版本(v6.1及更高版本)可以创建派生索引。
create index mytsidx on mytable
(timestamp(date('1900-12-31') + coldays days)
+ (floor(coltime / 10000) * 60*60
+ mod(floor(coltime / 100),100) * 60 mod(coltime, 100) )
seconds )
2)在旧版本中,您需要将传入时间戳转换为部分并进行比较,如下所示:
select * from mytable
where (strdays < coldays
or strdays = coldays and strtime <= coltime)
and (enddays > coldays
or enddays = coldays and endtime >= coltime)
如果你选择选项1,我建议创建一个UDF来处理转换。
create index mytsidx on mytable (CONVERT_TO_TS(coldays,coltime));
select * from mytable
where CONVERT_TO_TS(coldays,coltime)
between start_ts and end_ts;