所以我有一个名为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);
我在这里错过了什么吗?预先感谢。
答案 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秒,以确保我们正在处理时间戳)。
答案 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,例如DATE
或hr - 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;