Sql 将毫秒移动一个位置值
由于(我的错误),我现在在oracle数据库中有数千个时间戳不正确的条目。 问题如下: 2018-06-26 11:15:43的时间戳。950已作为 2014年2月26日上午11.15.43.095000000 有没有缩小毫秒的功能?我只发现,使用一些to_char、to_date函数和子字符串,我可以“删除”毫秒前的0,但在我看来,它的分辨率不够好 提前谢谢 编辑:不幸的是,我无法使用正确的算法重新上传数据。您可以使用Sql 将毫秒移动一个位置值,sql,oracle,timestamp,milliseconds,Sql,Oracle,Timestamp,Milliseconds,由于(我的错误),我现在在oracle数据库中有数千个时间戳不正确的条目。 问题如下: 2018-06-26 11:15:43的时间戳。950已作为 2014年2月26日上午11.15.43.095000000 有没有缩小毫秒的功能?我只发现,使用一些to_char、to_date函数和子字符串,我可以“删除”毫秒前的0,但在我看来,它的分辨率不够好 提前谢谢 编辑:不幸的是,我无法使用正确的算法重新上传数据。您可以使用TRUNC(time,'MI')获取没有秒组件的时间(作为日期数据类型,然后
TRUNC(time,'MI')
获取没有秒组件的时间(作为日期数据类型,然后可以使用CAST
转换回时间戳)。然后,您可以使用提取(时间中的秒)
获得秒(包括分数秒)分量,并将其拆分为秒和毫秒分量(后者您只需乘以10即可执行校正)然后使用NUMTODSINTERVAL
将数值转换为可以添加到截断时间戳中的间隔
像这样:
Oracle 11g R2架构设置:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
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 |
查询1:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
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 |
:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
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 |
但是,如果可以的话,您最好使用正确的算法再次上传源数据中的时间戳,因为您将丢失毫秒中的最低有效位。您可以使用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;
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 |
查询1:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
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 |
:
CREATE TABLE times ( time ) AS
SELECT TIMESTAMP '2018-06-26 11:15:43.095' FROM DUAL;
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 |
但是,您最好使用正确的算法再次从源数据上传时间戳(如果可以的话),因为您将丢失毫秒中的最低有效位。不幸的是,您的数据永远被损坏。无法区分移位的时间戳和正确的时间戳:
2018-06-26 11:15:43.950
2018-06-26 11:15:43.095
两者都会产生以下时间戳
26-FEB-18 11.15.43.095000000 AM
不幸的是,您的数据永远被破坏。无法区分移动的时间戳和正确的时间戳:
2018-06-26 11:15:43.950
2018-06-26 11:15:43.095
两者都会产生以下时间戳
26-FEB-18 11.15.43.095000000 AM
最佳选择:修复代码后,从原始源重新加载数据 如果您不再有权访问原始数据,并且必须将其全部修复到位,请使用下面的UPDATE语句(如上下文所示): 说明: 如果原始时间戳的格式为
X+w
,其中X
为整秒,w
为小数点后的第二部分,则当前值为X+z
,其中z=w/10
(您在小数点后添加了一个错误0
,这意味着您将w
除以10)。因此:您当前拥有X+z
,但您想要X+w
,或者换句话说,X+10*z
。因此,您必须将9*z
添加到现有的内容中
要获得z
(时间戳的小数部分),您需要从时间戳中减去X
(整数部分)。X
本身就是将时间戳截断为整秒。没有TRUNC()
函数截断为整秒,但是将函数转换为时间戳(0)
这项工作做得很好
要使用示例数据:X
是时间戳'2018-06-26 11:15:43.000000'
。这也是转换的结果(ts作为时间戳(0))w
是.9500
和z
是您的表中的.0950
。您当前的值是X+z
,但您需要X+w
。也就是X+10*z=(X+z)+9*z
,现在请记住(X+z)
只是ts
(当前表中的值)因此只需将值z
添加九倍,这就是差异(ts-X)
最佳选项:修复代码后从原始源重新加载数据
如果您不再有权访问原始数据,并且必须将其全部修复到位,请使用下面的UPDATE语句(如上下文所示):
说明:
如果原始时间戳的格式为X+w
,其中X
为整秒,w
为小数点后的第二部分,则当前值为X+z
,其中z=w/10
(您在小数点后添加了一个错误0
,这意味着您将w
除以10)。因此:您当前拥有X+z
,但您想要X+w
,或者换句话说,X+10*z
。因此,您必须将9*z
添加到现有的内容中
要获得z
(时间戳的小数部分),您需要从时间戳中减去X
(整数部分)。X
本身就是将时间戳截断为整秒。没有TRUNC()
函数截断为整秒,但是将函数转换为时间戳(0)
这项工作做得很好
要使用示例数据:X
是时间戳'2018-06-26 11:15:43.000000'
。这也是cast(ts as timestamp(0))
w
是.9500
和