如何使用TIMEZONE列获取timestamp(4)的前一个小时?

时间:2018-08-06 21:23:43

标签: sql oracle

所以我有一个名为Value的表。我正在尝试导出最近一小时的值(使用时区的 HR-> Timestamp(4) ),以便可以在此条件语句中使用它我正在构建的存储过程。但是,当我尝试以下操作时,Oracle只返回日期( 01-Jan-19 )而不是前一个小时( 19-Jan-19 01.00.00.00000000 UTC )。我究竟做错了什么?

select hr
     , hr - (1/24) as Converted
 from value;

如果我尝试以下操作,则返回“ 31-DEC-16 12.00.00.000000000 AM ”作为“已转换”的值(无论HR的值是多少):

select hr
     , to_timestamp(hr - (1/24)) as converted
   from value;

最终将在我的存储过程中将其用作变量的定义:

 select max(value) 
   into v_Previous_hour
   from value
  where hr = hr - (1/24);

我在这里错过了什么吗?预先感谢。

5 个答案:

答案 0 :(得分:1)

尝试一下:

select hr
     , cast( hr - (1/24) as timestamp) as Converted
 from value;

此外,下面的查询将不会执行您认为的操作。

 select max(value) 
   into v_Previous_hour
   from value
  where hr = hr - (1/24);

答案 1 :(得分:1)

或者您可以使用INTERVAL

SELECT TO_CHAR(HR) AS HR,
       TO_CHAR(CAST(HR - INTERVAL '1' HOUR - INTERVAL '0.233' SECOND AS TIMESTAMP(4) WITH TIME ZONE)) AS HR_MINUS_ONE_HOUR
  FROM VAL;

(在这里,根据@AlexPoole对@OldProgrammer答案的评论,我另外减去了0.233秒,以确保我们正在处理时间戳)。

SQLFiddle here

答案 2 :(得分:1)

  

Oracle仅返回日期(19年1月1日)

日期仍然有时间,您的客户没有向您显示日期。您可以使用to_char()来明确显示它:

select to_char(hr - (1/24), 'YYYY-MM-DD HH24:MI:SS') from ...

这是一个日期,因为[这是时间戳-数字的结果]算术,并且时间戳被隐式转换为减法之前的日期。但是您将丢失原始值的小数秒时区。即使您回退到普通时间戳,信息也不会恢复,并且即使您回退到带有时区的时间戳,它也会非法获取当前会话的时区,因此不一定匹配。

要同时保留两者,您可以按照答案中的建议进行操作,或者

select hr - interval '1' hour from ...

在您的过程中,声明一个具有相同数据类型的变量,例如(作为非块):

declare
  l_hr value.hr%type;
begin
  select hr - interval '1' hour
  into l_hr
  from value
  where ... ;

  ...
end;

不要试图将值存储为字符串或将其用作字符串的原始数据类型。使用起来更容易,更安全,更高效。

答案 3 :(得分:1)

看看这张桌子Matrix of Datetime Arithmetic

当您执行import openpyxl wb = openpyxl.load_workbook('TestBook') ws = wb.get_sheet_by_name('Sheet1') num_of_twos = [c.value for c in ws["C"]].count(2) 时,您将获得{TIMESTAMP WITH TIME ZONE} - {NUMERIC}的值,即您松开了时区信息。

最好使用INTERVAL,例如DATEhr - INTERVAL '1' HOUR

无论如何,我不明白你的问题。如果您问“ 如何使用TIMEZONE列获取时间戳(4)的前一个小时?”,那么我的答案将是

hr - NUMTODSINTERVAL(1, 'HOUR')

请注意,解决方案SELECT EXTRACT(HOUR FROM hr - INTERVAL '1' HOUR) AS Solution_1 TO_CHAR(hr - INTERVAL '1' HOUR, 'HH24') AS Solution_2 FROM ... 始终返回UTC时间的小时,而EXTRACT(HOUR FROM hr - INTERVAL '1' HOUR)返回所存储的时区的小时。

答案 4 :(得分:0)

经过2个小时的梳理(具有讽刺意味的是,在OldProgrammer足够好为我提供答案之后),我找到了一种解决方法:

 select hr
      , hr - numtodsinterval(1, 'hour') as converted
   from value;