AS400 / DB2 - 将基于整数的日期和时间转换为时间戳?

时间:2015-10-17 20:52:56

标签: sql ibm-midrange

我有4条用户输入:startDateendDatestartTimeendTime

数据库中的日期和时间设置与我之前使用的任何设置不同。日期是自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

当您需要在两个日期之间找到两次日期之类的项目时会出现问题,因为它会过滤掉每天两次之间的任何日期。我知道有一种方法可以创建一个时间戳,但是我很难用两个整数把它放在查询中。

我有哪些选择来解决这个问题?

2 个答案:

答案 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;