因此,如果符合条件,我有一些逻辑将尝试获取与前一个小时相关的值(VALUE)。 HOUR列是带有TIME ZONE的TIMESTAMP列。我以为我可以运行以下查询,但是出现 ORA-00932数据类型不一致:预期的TIMESTAMP WITH TIME ZONE出现NUMBER 错误。我必须在“带时区的时间戳”值中添加某种转换功能吗?
以下是我的查询代码:
SELECT MAX(VALUE)
FROM VALUE V
WHERE CODE = 'HI'
AND HR = '15-JAN-17 05.00.00.000000000 AM' - (1/24);
谢谢。
答案 0 :(得分:2)
使用TO_TIMESTAMP将'15-JAN-17 05.00.00.000000000 AM'
设置为日期时间,然后减去一小时。
SELECT MAX(VALUE)
FROM VALUE V
WHERE CODE = 'HI'
AND HR = TO_TIMESTAMP('15-JAN-17 05.00.00.000000000 AM','DD-MON-RR HH.MI.SS.FF AM') - (1/24);
答案 1 :(得分:2)
'15-JAN-17 05.00.00.000000000 AM'
是字符串,而不是时间戳。您可以按照@ D-Shih的建议将其转换为时间戳(无时区),但应指定格式掩码和日期语言,而不要依赖NLS设置:
AND HR = to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH') - (1/24);
或者它是一个固定值(大概不是,或者您可以更改该文字):
AND HR = timestamp '2017-01-15 05:00:00' - (1/24);
从时间戳中减去几天会得到一个日期结果,所以您也许真的想做:
AND HR = timestamp '2017-01-15 05:00:00' - interval '1' hour;
现在它保留为时间戳,但是您没有时区信息。如果您知道时区,则可以将其包含在字符串文字和格式掩码中,或者包含在时间戳文字中,例如:
AND HR = timestamp '2017-01-15 05:00:00 America/Los_Angeles' - (1/24);
或者从您的原始字符串开始,如果您只需要使用它,则可以使用from_tz()
:
AND HR = from_tz(to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH'), 'America/Los_Angeles') - interval '1' hour;
最后进行间隔减法意味着它可以正确处理DST。
从您的字符串值开始的各种转换的演示:
alter session set nls_date_format = 'YYYY-MM-DD HH24:MI:SS';
alter session set nls_timestamp_format = 'YYYY-MM-DD HH24:MI:SS.FF1';
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS.FF1 TZR TZD';
select
to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH') as a_timestamp,
to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH') - (1/24) as b_date,
to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH') - interval '1' hour as c_timestamp,
from_tz(to_timestamp('15-JAN-17 05.00.00.000000000 AM', 'DD-MON-RR HH.MI.SS.FF AM',
'NLS_DATE_LANGUAGE=ENGLISH'), 'America/Los_Angeles') - interval '1' hour as d_timestamp_tz
from dual;
A_TIMESTAMP B_DATE C_TIMESTAMP D_TIMESTAMP_TZ
--------------------- ------------------- --------------------- ---------------------------------------------
2017-01-15 05:00:00.0 2017-01-15 04:00:00 2017-01-15 04:00:00.0 2017-01-15 04:00:00.0 AMERICA/LOS_ANGELES PST