在 oracle sql 中查找时间差
Finding the difference of times in oracle sql
我有一个 table 有两列(数据类型是 varchar2)有时间戳。我想找出时间戳的区别,即; ADDITIONAL_COLUMN2 和 ADDITIONAL_COLUMN1 之间的时间戳差异。
我的 table 列:
我试过下面的代码,但它给我错误。
SELECT (extract(DAY FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*24*60*60)+
(extract(HOUR FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*60*60)+
(extract(MINUTE FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*60)+
extract(SECOND FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1) into diff
FROM Table;
Error: missing keyword.
查询:
SELECT (extract(DAY FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*24*60*60)+
(extract(HOUR FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*60*60)+
(extract(MINUTE FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*60)+
extract(SECOND FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))
FROM MISIMD_FOM_SPM_AUDIT;
查询 2:
with cte (diff) as (
select to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
- to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
as diff
from MISIMD_FOM_SPM_AUDIT
)
select (extract(day from diff)*24*60*60)
+ (extract(hour from diff)*60*60)
+ (extract(minute from diff)*60)
+ extract(second from diff) as diff
from cte;
此查询为我提供了所需的输出。
Output of Query 2
我执行以下测试用例,它显然使用了我自己的 NLS 设置:
PARAMETER VALUE
---------------------------------------- ----------------------------------------
NLS_RDBMS_VERSION 12.2.0.1.0
NLS_NCHAR_CONV_EXCP FALSE
NLS_LENGTH_SEMANTICS BYTE
NLS_COMP BINARY
NLS_DUAL_CURRENCY $
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_SORT BINARY
NLS_DATE_LANGUAGE AMERICAN
PARAMETER VALUE
---------------------------------------- ----------------------------------------
NLS_DATE_FORMAT DD-MON-RR
NLS_CALENDAR GREGORIAN
NLS_NUMERIC_CHARACTERS .,
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET AL32UTF8
NLS_ISO_CURRENCY AMERICA
NLS_CURRENCY $
NLS_TERRITORY AMERICA
NLS_LANGUAGE AMERICAN
SQL> create table my_test ( c1 timestamp , c2 timestamp ) ;
Table created.
SQL> insert into my_test values ( systimestamp , null ) ;
1 row created.
SQL> -- I wait for a couple of seconds
SQL> update my_test set c2=systimestamp ;
1 row updated.
SQL> commit;
Commit complete.
SQL> col c1 for a40
SQL> col c2 for a40
SQL> select c1,c2 from my_test ;
C1 C2
---------------------------------------- ----------------------------------------
30-JUN-20 11.03.01.262132 AM 30-JUN-20 11.03.16.079616 AM
SQL> SELECT (extract(DAY FROM c2-C1)*24*60*60)+
2 (extract(HOUR FROM C2-C1)*60*60)+
3 (extract(MINUTE FROM C2-C1)*60)+
4 extract(SECOND FROM C2-C1)
5* FROM my_test
SQL> /
(EXTRACT(DAYFROMC2-C1)*24*60*60)+(EXTRACT(HOURFROMC2-C1)*60*60)+(EXTRACT(MINUTEFROMC2-C1)*60)+EXTRACT(SECONDFROMC2-C1)
----------------------------------------------------------------------------------------------------------------------
14.817484
SQL>
您不能将 INTO 放入查询中,即 PL/SQL,而不是 SQL。这到底是什么问题,因为你的查询对我有用,只要我删除了它的 INTO 部分。
更新答案
由于您的情况使用 varchar2 作为时间戳列并使用它存储时区(如果您问我这是没有意义的),情况就不同了。您需要对查询应用转换以将 varchar2 转换为正确的时间戳。
SQL> create table my_test ( c1 varchar2(100), c2 varchar2(100) );
Table created.
SQL> insert into my_test values ( to_char(systimestamp) , null );
1 row created.
SQL> update my_test set c2=to_char(systimestamp) ;
1 row updated.
SQL> commit;
Commit complete.
SQL> set lines 200
SQL> col c1 for a50
SQL> col c2 for a50
SQL> select c1,c2 from my_test ;
C1 C2
-------------------------------------------------- --------------------------------------------------
30-JUN-20 11.12.11.094964 AM +02:00 30-JUN-20 11.12.26.082914 AM +02:00
在这里您可以看到值存储为 varchar2,但带有时区格式的时间戳。
SQL> select to_timestamp_tz(c1) , to_timestamp_tz(c2) from my_test ;
TO_TIMESTAMP_TZ(C1) TO_TIMESTAMP_TZ(C2)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
30-JUN-20 11.12.11.094964000 AM +02:00 30-JUN-20 11.12.26.082914000 AM +02:00
现在,您之前使用的相同查询
SQL> SELECT (extract(DAY FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*24*60*60)+
2 (extract(HOUR FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*60*60)+
3 (extract(MINUTE FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*60)+
4 extract(SECOND FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))
FROM my_test; 5
(EXTRACT(DAYFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*24*60*60)+(EXTRACT(HOURFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*60*60)+(EXTRACT(MINUTEFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*60)+EXT
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
14.98795
SQL>
希望对您有所帮助。
“ORA-00905: 缺少关键字”错误是因为您有 into
而不是 as
;更改:
... AS diff
now works,但是...
i changed into to as. I was getting the below error ORA-30076: invalid extract field for extract source
这意味着您的列实际上不是时间戳,they're strings,因此您需要先将它们转换为实际时间戳:
with cte (ts1, ts2) as (
select to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM'),
to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
from your_table
)
select (extract(day from ts2-ts1)*24*60*60)
+ (extract(hour from ts2-ts1)*60*60)
+ (extract(minute from ts2-ts1)*60)
+ extract(second from ts2-ts1) as diff
from cte;
或者也在 CTE 中进行计算:
with cte (diff) as (
select to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
- to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
as diff
from your_table
)
select (extract(day from diff)*24*60*60)
+ (extract(hour from diff)*60*60)
+ (extract(minute from diff)*60)
+ extract(second from diff) as diff
from cte;
我有一个 table 有两列(数据类型是 varchar2)有时间戳。我想找出时间戳的区别,即; ADDITIONAL_COLUMN2 和 ADDITIONAL_COLUMN1 之间的时间戳差异。
我的 table 列:
我试过下面的代码,但它给我错误。
SELECT (extract(DAY FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*24*60*60)+
(extract(HOUR FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*60*60)+
(extract(MINUTE FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1)*60)+
extract(SECOND FROM ADDITIONAL_COLUMN2-ADDITIONAL_COLUMN1) into diff
FROM Table;
Error: missing keyword.
查询:
SELECT (extract(DAY FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*24*60*60)+
(extract(HOUR FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*60*60)+
(extract(MINUTE FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))*60)+
extract(SECOND FROM to_timestamp_tz(ADDITIONAL_COLUMN2)-to_timestamp_tz(ADDITIONAL_COLUMN1))
FROM MISIMD_FOM_SPM_AUDIT;
查询 2:
with cte (diff) as (
select to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
- to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
as diff
from MISIMD_FOM_SPM_AUDIT
)
select (extract(day from diff)*24*60*60)
+ (extract(hour from diff)*60*60)
+ (extract(minute from diff)*60)
+ extract(second from diff) as diff
from cte;
此查询为我提供了所需的输出。 Output of Query 2
我执行以下测试用例,它显然使用了我自己的 NLS 设置:
PARAMETER VALUE
---------------------------------------- ----------------------------------------
NLS_RDBMS_VERSION 12.2.0.1.0
NLS_NCHAR_CONV_EXCP FALSE
NLS_LENGTH_SEMANTICS BYTE
NLS_COMP BINARY
NLS_DUAL_CURRENCY $
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_SORT BINARY
NLS_DATE_LANGUAGE AMERICAN
PARAMETER VALUE
---------------------------------------- ----------------------------------------
NLS_DATE_FORMAT DD-MON-RR
NLS_CALENDAR GREGORIAN
NLS_NUMERIC_CHARACTERS .,
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_CHARACTERSET AL32UTF8
NLS_ISO_CURRENCY AMERICA
NLS_CURRENCY $
NLS_TERRITORY AMERICA
NLS_LANGUAGE AMERICAN
SQL> create table my_test ( c1 timestamp , c2 timestamp ) ;
Table created.
SQL> insert into my_test values ( systimestamp , null ) ;
1 row created.
SQL> -- I wait for a couple of seconds
SQL> update my_test set c2=systimestamp ;
1 row updated.
SQL> commit;
Commit complete.
SQL> col c1 for a40
SQL> col c2 for a40
SQL> select c1,c2 from my_test ;
C1 C2
---------------------------------------- ----------------------------------------
30-JUN-20 11.03.01.262132 AM 30-JUN-20 11.03.16.079616 AM
SQL> SELECT (extract(DAY FROM c2-C1)*24*60*60)+
2 (extract(HOUR FROM C2-C1)*60*60)+
3 (extract(MINUTE FROM C2-C1)*60)+
4 extract(SECOND FROM C2-C1)
5* FROM my_test
SQL> /
(EXTRACT(DAYFROMC2-C1)*24*60*60)+(EXTRACT(HOURFROMC2-C1)*60*60)+(EXTRACT(MINUTEFROMC2-C1)*60)+EXTRACT(SECONDFROMC2-C1)
----------------------------------------------------------------------------------------------------------------------
14.817484
SQL>
您不能将 INTO 放入查询中,即 PL/SQL,而不是 SQL。这到底是什么问题,因为你的查询对我有用,只要我删除了它的 INTO 部分。
更新答案
由于您的情况使用 varchar2 作为时间戳列并使用它存储时区(如果您问我这是没有意义的),情况就不同了。您需要对查询应用转换以将 varchar2 转换为正确的时间戳。
SQL> create table my_test ( c1 varchar2(100), c2 varchar2(100) );
Table created.
SQL> insert into my_test values ( to_char(systimestamp) , null );
1 row created.
SQL> update my_test set c2=to_char(systimestamp) ;
1 row updated.
SQL> commit;
Commit complete.
SQL> set lines 200
SQL> col c1 for a50
SQL> col c2 for a50
SQL> select c1,c2 from my_test ;
C1 C2
-------------------------------------------------- --------------------------------------------------
30-JUN-20 11.12.11.094964 AM +02:00 30-JUN-20 11.12.26.082914 AM +02:00
在这里您可以看到值存储为 varchar2,但带有时区格式的时间戳。
SQL> select to_timestamp_tz(c1) , to_timestamp_tz(c2) from my_test ;
TO_TIMESTAMP_TZ(C1) TO_TIMESTAMP_TZ(C2)
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
30-JUN-20 11.12.11.094964000 AM +02:00 30-JUN-20 11.12.26.082914000 AM +02:00
现在,您之前使用的相同查询
SQL> SELECT (extract(DAY FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*24*60*60)+
2 (extract(HOUR FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*60*60)+
3 (extract(MINUTE FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))*60)+
4 extract(SECOND FROM to_timestamp_tz(c2)-to_timestamp_tz(C1))
FROM my_test; 5
(EXTRACT(DAYFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*24*60*60)+(EXTRACT(HOURFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*60*60)+(EXTRACT(MINUTEFROMTO_TIMESTAMP_TZ(C2)-TO_TIMESTAMP_TZ(C1))*60)+EXT
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
14.98795
SQL>
希望对您有所帮助。
“ORA-00905: 缺少关键字”错误是因为您有 into
而不是 as
;更改:
... AS diff
now works,但是...
i changed into to as. I was getting the below error ORA-30076: invalid extract field for extract source
这意味着您的列实际上不是时间戳,they're strings,因此您需要先将它们转换为实际时间戳:
with cte (ts1, ts2) as (
select to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM'),
to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
from your_table
)
select (extract(day from ts2-ts1)*24*60*60)
+ (extract(hour from ts2-ts1)*60*60)
+ (extract(minute from ts2-ts1)*60)
+ extract(second from ts2-ts1) as diff
from cte;
或者也在 CTE 中进行计算:
with cte (diff) as (
select to_timestamp_tz(additional_column2, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
- to_timestamp_tz(additional_column1, 'YYYY-MM-DD"T"HH24:MI:SS.FFTZH:TZM')
as diff
from your_table
)
select (extract(day from diff)*24*60*60)
+ (extract(hour from diff)*60*60)
+ (extract(minute from diff)*60)
+ extract(second from diff) as diff
from cte;