Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将毫秒移动一个位置值_Sql_Oracle_Timestamp_Milliseconds - Fatal编程技术网

Sql 将毫秒移动一个位置值

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')获取没有秒组件的时间(作为日期数据类型,然后

由于(我的错误),我现在在oracle数据库中有数千个时间戳不正确的条目。 问题如下:

2018-06-26 11:15:43的时间戳。950已作为 2014年2月26日上午11.15.43.095000000

有没有缩小毫秒的功能?我只发现,使用一些to_char、to_date函数和子字符串,我可以“删除”毫秒前的0,但在我看来,它的分辨率不够好

提前谢谢

编辑:不幸的是,我无法使用正确的算法重新上传数据。

您可以使用
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