我的表名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
。
由于表中有许多记录应该是什么解决方案
创建新表(mytable),然后将数据插入其中
有没有办法对将字符串转换为时间戳的数据进行排序 然后 得到结果?
答案 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>