将毫秒移动一个位置值
Move milliseconds by one position value
由于 "incorrect" java parsing date(我的错)我现在在 oracle DB 中有几千个时间戳不正确的条目。
问题如下:
2018-06-26 11:15:43.950 的时间戳已作为
26-FEB-18 11.15.43.095000000 上午
有没有缩小毫秒的功能?我只是想通了一些 to_char , to_date 函数结合子字符串我可以 "remove" 0 在毫秒前面,但在我看来分辨率不够好。
提前致谢!
编辑:不幸的是,我无法使用更正的算法重新上传数据。
您可以使用 TRUNC( time, 'MI' )
获取没有秒部分的时间(作为日期数据类型,然后您可以使用 CAST
将其转换回时间戳)。然后,您可以使用 EXTRACT( SECOND from time )
获取秒(包括小数秒)组件并将其拆分为秒和毫秒组件(后者只需乘以 10 即可执行校正),然后使用 NUMTODSINTERVAL
将数值转换为可以添加到截断时间戳的间隔。
像这样:
Oracle 11g R2 架构设置:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
查询 1:
SELECT time,
CAST( TRUNC( time, 'MI' ) AS TIMESTAMP )
+ NUMTODSINTERVAL(
TRUNC( EXTRACT( SECOND FROM time ) )
+ MOD( EXTRACT( SECOND FROM time ), 1 ) * 10,
'SECOND'
) As updated_time
FROM times
| TIME | UPDATED_TIME |
|-------------------------|------------------------|
| 2018-06-26 11:15:43.095 | 2018-06-26 11:15:43.95 |
但是,您最好使用更正的算法再次(如果可以)从您的源数据上传时间戳,因为您将丢失毫秒中的 least-significant 数字。
很遗憾,您的数据永远损坏了。无法区分移动时间戳和正确时间戳:
2018-06-26 11:15:43.950
2018-06-26 11:15:43.095
两者都会产生以下时间戳
26-FEB-18 11.15.43.095000000 AM
最佳选择:修复代码后从原始来源重新加载数据。
如果您无法再访问原始数据,并且必须就地修复所有数据,请使用下面的 UPDATE 语句(如上下文所示):
create table tbl ( ts timestamp );
insert into tbl ( ts ) values ( timestamp '2018-06-26 11:15:43.0950' );
commit;
select ts from tbl;
TS
----------------------------------------
2018-06-26 11.15.43.095000000
update tbl set ts = ts + 9 * (ts - cast(ts as timestamp(0)));
1 row updated.
commit;
select ts from tbl;
TS
----------------------------------------
2018-06-26 11.15.43.950000000
解释:
如果您的原始时间戳的格式为 X + w
,其中 X
是整数秒,w
是小数秒部分,则当前值为 X + z
,其中 z = w/10
。 (您在小数点后添加了一个错误的 0
,这意味着您将 w
除以十)。所以:你目前有 X + z
,但你想要 X + w
,或者换句话说,X + 10 * z
。因此,您必须将 9 * z
添加到您已有的内容中。
要获得 z
(时间戳的小数部分),您需要从时间戳中减去 X
(整数部分)。 X
本身就是将时间戳截断为整秒。没有 TRUNC()
函数可以截断整秒,但是 CAST
到 TIMESTAMP(0)
的函数可以很好地完成这项工作。
要使用您的示例数据:X
是时间戳 '2018-06-26 11:15:43.000000'
。这也是cast(ts as timestamp(0))
的结果。 w
是 .9500
,而 z
是使它成为您的 table、.0950
的原因。您当前的值为 X + z
,但您想要 X + w
。那就是 X + 10 * z = (X + z) + 9 * z
,现在记住 (X + z)
只是 ts
(你目前在 table 中的值)所以你只需要加上九倍的值 z
,也就是差值(ts - X)
.
由于 "incorrect" java parsing date(我的错)我现在在 oracle DB 中有几千个时间戳不正确的条目。 问题如下:
2018-06-26 11:15:43.950 的时间戳已作为 26-FEB-18 11.15.43.095000000 上午
有没有缩小毫秒的功能?我只是想通了一些 to_char , to_date 函数结合子字符串我可以 "remove" 0 在毫秒前面,但在我看来分辨率不够好。
提前致谢!
编辑:不幸的是,我无法使用更正的算法重新上传数据。
您可以使用 TRUNC( time, 'MI' )
获取没有秒部分的时间(作为日期数据类型,然后您可以使用 CAST
将其转换回时间戳)。然后,您可以使用 EXTRACT( SECOND from time )
获取秒(包括小数秒)组件并将其拆分为秒和毫秒组件(后者只需乘以 10 即可执行校正),然后使用 NUMTODSINTERVAL
将数值转换为可以添加到截断时间戳的间隔。
像这样:
Oracle 11g R2 架构设置:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
查询 1:
SELECT time,
CAST( TRUNC( time, 'MI' ) AS TIMESTAMP )
+ NUMTODSINTERVAL(
TRUNC( EXTRACT( SECOND FROM time ) )
+ MOD( EXTRACT( SECOND FROM time ), 1 ) * 10,
'SECOND'
) As updated_time
FROM times
| TIME | UPDATED_TIME |
|-------------------------|------------------------|
| 2018-06-26 11:15:43.095 | 2018-06-26 11:15:43.95 |
但是,您最好使用更正的算法再次(如果可以)从您的源数据上传时间戳,因为您将丢失毫秒中的 least-significant 数字。
很遗憾,您的数据永远损坏了。无法区分移动时间戳和正确时间戳:
2018-06-26 11:15:43.950
2018-06-26 11:15:43.095
两者都会产生以下时间戳
26-FEB-18 11.15.43.095000000 AM
最佳选择:修复代码后从原始来源重新加载数据。
如果您无法再访问原始数据,并且必须就地修复所有数据,请使用下面的 UPDATE 语句(如上下文所示):
create table tbl ( ts timestamp );
insert into tbl ( ts ) values ( timestamp '2018-06-26 11:15:43.0950' );
commit;
select ts from tbl;
TS
----------------------------------------
2018-06-26 11.15.43.095000000
update tbl set ts = ts + 9 * (ts - cast(ts as timestamp(0)));
1 row updated.
commit;
select ts from tbl;
TS
----------------------------------------
2018-06-26 11.15.43.950000000
解释:
如果您的原始时间戳的格式为 X + w
,其中 X
是整数秒,w
是小数秒部分,则当前值为 X + z
,其中 z = w/10
。 (您在小数点后添加了一个错误的 0
,这意味着您将 w
除以十)。所以:你目前有 X + z
,但你想要 X + w
,或者换句话说,X + 10 * z
。因此,您必须将 9 * z
添加到您已有的内容中。
要获得 z
(时间戳的小数部分),您需要从时间戳中减去 X
(整数部分)。 X
本身就是将时间戳截断为整秒。没有 TRUNC()
函数可以截断整秒,但是 CAST
到 TIMESTAMP(0)
的函数可以很好地完成这项工作。
要使用您的示例数据:X
是时间戳 '2018-06-26 11:15:43.000000'
。这也是cast(ts as timestamp(0))
的结果。 w
是 .9500
,而 z
是使它成为您的 table、.0950
的原因。您当前的值为 X + z
,但您想要 X + w
。那就是 X + 10 * z = (X + z) + 9 * z
,现在记住 (X + z)
只是 ts
(你目前在 table 中的值)所以你只需要加上九倍的值 z
,也就是差值(ts - X)
.