我尝试根据同一小时创建的行数进行报告,并且我尝试使用提取功能对行进行分组,但它会更改结果信息,因为例如:
select
to_char(resolved_time,'YY/MM/DD') Day,
to_char(resolved_time, 'HH24') hour_tmp,
extract(hour from resolved_time) Hour
from RESOLUTION_HISTORY h
where resolved_time >= timestamp '2017-01-01 00:00:00'
and resolved_time < timestamp '2017-01-02 00:00:00'
and modified_by in 'user1'
order by 2;
我的结果看起来像这样:
Day Hour_Tmp Hour
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 14 20
17/01/01 15 21
17/01/01 17 23
17/01/01 17 23
17/01/01 18 0
正如你所看到的,解析时间和提取的实际值之间存在差异,试图改变我的会话但它似乎没有帮助。 是否还有其他选项可以在本地会话中更改此设置?
答案 0 :(得分:2)
您看到的差异是UTC与您的列值相关的时区之间的偏差。您可以看到简化版本:
select extract(hour from timestamp '2017-01-01 00:00:00 America/New_York') from dual;
EXTRACT(HOURFROMTIMESTAMP'2017-01-0100:00:00AMERICA/NEW_YORK')
--------------------------------------------------------------
5
DBTIMEZONE
按照建议使用+00:00,数据库服务器在BST上,我的会话也是BST(通过欧洲/伦敦)。但这些都不相关。
从具有时区值的日期时间中提取时,返回的值为UTC。
(如果您的专栏为timestamp with local time zone
,您会在会话时区看到小时,这可能更不实用。)
您可以通过将列转换为纯时间戳来解决此问题,这实际上会截断时区信息:
extract(hour from cast(resolved_time as timestamp))
使用您的数据,您可以看到与以下内容的区别:
select
to_char(resolved_time,'YYYY-MM-DD HH24:MI:SS TZR') full_value,
to_char(resolved_time,'YY/MM/DD') Day,
to_char(resolved_time, 'HH24') hour_tmp,
extract(hour from resolved_time) Hour_utc,
extract(hour from cast(resolved_time as timestamp)) Hour
from RESOLUTION_HISTORY h
where resolved_time >= timestamp '2017-01-01 00:00:00 America/New_York'
and resolved_time < timestamp '2017-01-02 00:00:00 America/New_York'
and modified_by in 'user1'
order by 2;
FULL_VALUE DAY HO HOUR_UTC HOUR
---------------------------------------------------- -------- -- ---------- ----------
2017-01-01 12:00:00 AMERICA/NEW_YORK 17/01/01 12 17 12
顺便提一下,我在过滤条件中包含了(假设的)列时区值,因此它不必依赖于您的会话时区。如果您有来自多个时区的值,那么您也需要在过滤器中允许这样做,并且可能需要在提取和分组之前将列值转换为特定区域。取决于你想要做的事情。