如何将字符串转换为时间戳,然后选择记录..?

时间:2017-04-21 15:26:05

标签: sql oracle

我的表名mytable如下所示..

ID      LOCATION    TIMERECORDED            
45744   20          2017-04-21 19:00:00.000 
45788   55          2017-04-21 19:15:00.000 
45832   55          2017-04-21 19:30:00.000 

此处TIMERECORDED列数据类型为varchar

我想获得25分钟内插入的最高记录 我写了下面的查询

select  *
from    mytable t
where   t.location_id = ? and
        t.time_recorded >= CURRENT_TIMESTAMP - NUMTODSINTERVAL(25,'MINUTE') and
        ROWNUM <= 1
order by t.time_recorded DESC

因为TIMERECORDED列数据的类型为varchar,我可以将数据类型转换为Timestamp然后获取结果..?

更新:

最近,DBA迁移了MSSQL DB to ORACLE数据库,但不幸的是,上表(mytable)列(TIMERECORDED)的数据类型为nvarchar

由于表中有许多记录应该是什么解决方案

  1. 创建新表(mytable),然后将数据插入其中

  2. 有没有办法对将字符串转换为时间戳的数据进行排序 然后     得到结果?

2 个答案:

答案 0 :(得分:0)

SELECT  * FROM    
  mytable t
WHERE   
  t.location_id = ? 
 AND
  to_timestamp(t.time_recorded, 'YYYY-MM-DD HH24:MI:SS') >= CURRENT_TIMESTAMP - NUMTODSINTERVAL(25,'MINUTE') 
 AND
  ROWNUM <= 1

ORDER BY t.time_recorded DESC

答案 1 :(得分:0)

您可以将列值转换为时间戳以与最后25分钟值进行比较,但由于字符串采用可比较的格式,您也可以将该目标值转换为字符串:

select *
from (
  select  *
  from    mytable t
  where   t.location_id = ? and
          t.time_recorded >= to_char(CURRENT_TIMESTAMP - NUMTODSINTERVAL(25,'MINUTE'),
            'YYYY-MM-DD HH24:MI:SS.FF3')
  order by t.time_recorded DESC
)
where ROWNUM <= 1;

您需要在应用rownum过滤器之前订购结果,因此我将大部分原始查询放入内联视图(子查询),并将fownum过滤器移到

你的样本有三行和?替换为55,其输出为:

        ID LOCATION_ID TIME_RECORDED          
---------- ----------- -----------------------
     45832          55 2017-04-21 19:30:00.000

(我的当地时间实际上是19:00,当我跑了,但过滤器仍然有效)

正如评论中所述,正如您所知,理想情况下您应该更改列数据类型。正如@mathguy建议的那样,您或您的DBA)可以添加和填充新列,验证其数据是否正确,然后删​​除旧列并重命名新列。快速概述:

alter table mytable add (new_time_recorded timestamp);
update mytable set new_time_recorded =
  to_timestamp(time_recorded, 'YYYY-MM-DD HH24:MI:SS.FF3');
alter table mytable drop (time_recorded);
alter table mytable rename column new_time_recorded to time_recorded;

然后你可以进行类似的查询但没有数据类型转换:

select *
from (
  select  *
  from    mytable t
  where   t.location_id = 55 and
          t.time_recorded >= CURRENT_TIMESTAMP - NUMTODSINTERVAL(25,'MINUTE')
  order by t.time_recorded DESC
)
where ROWNUM <= 1;

        ID LOCATION_ID TIME_RECORDED               
---------- ----------- ----------------------------
     45832          55 21-APR-17 19.30.00.000000000

如果旧列已编入索引或有任何约束,则您需要为新列重新创建这些列。

如果您描述该表或执行select *,则新列将显示在最后,即使旧列不是;但希望您没有任何假定或依赖列顺序的代码。如果你这样做,那么你必须创建一个表的副本,使用你的代码所需的顺序列,这可能会有更多的副作用 - 特权,触发器等等。 / p>