如何从 Oracle 中的当前时间获得 24 小时倒退时间
How to get 24 hours back time from current time in Oracle
我的 Oracle 数据库中有一列以下列格式记录用户的创建时间
30-NOV-20 11.49.11.000000000 AM
(TIMESTAMP(6) 格式)。
我想做的是 select 所有创建时间比当前时间早 24 小时的记录
所以我要做的是从当前时间减去 1 并进行比较。但是当我减去 1 时,它 returns 只有日期。
select * from user where created_date < SYSTIMESTAMP-1
dbms_output.put_line (SYSTIMESTAMP-1);
-->29-NOV-20
缺少时间部分,这让我无法与 table 中创建的时间进行比较
请帮我完成这个任务。
如果您从 date
数据类型(例如 sysdate
)中减去 1
,它会让您倒退一天。但是,如果您从 timestamp
数据类型值中减去它,Oracle 会将其转换为 date 和 return 日期(此外,它将被截断)。
参见以下示例:
SQL> select
2 systimestamp val1,
3 systimestamp - 1 val2,
4 --
5 systimestamp - interval '1' day val3
6 from dual;
VAL1
-----------------------------------------------------
VAL2
--------
VAL3
-----------------------------------------------------
30.11.20 09:55:01,439352 +01:00
29.11.20
29.11.20 09:55:01,439352000 +01:00
SQL>
所以,你应该做的是减去一个间隔,即
select *
from user
where created_date < systimestamp - interval '1' day;
您可以将其用作 (SYSDATE, -1)。
另外,如果要搜索24小时内的新记录,应该是"created_date> = (sysdate-1)".
一半的问题是,无论使用什么客户端程序来显示值,都使用 作为其领土,并且默认格式设置为 DD-MON-RR
.
您可以更改 NLS_DATE_FORMAT
和 NLS_TIMESTAMP_FORMAT
会话参数,这将(假设您的客户端程序使用它们而不是某些内部设置)为您提供您期望的输出:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF9';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF9TZR';
然后
SELECT SYSDATE, SYSTIMESTAMP FROM DUAL;
输出(取决于您的系统时区):
SYSDATE | SYSTIMESTAMP
:------------------ | :----------------------------------
2020-11-30 10:12:22 | 2020-11-30 10:12:22.476282000+00:00
如果您使用 SYSTIMESTAMP-1
,则 Oracle 不支持从 TIMESTAMP [WITH TIME ZONE]
数据类型中减去 NUMBER
数据类型,但它支持从中减去 NUMBER
数据类型DATE
数据类型并将执行从 TIMESTAMP
到 DATE
的隐式转换,以便查询有效。
例如:
SELECT SYSDATE - 1, SYSTIMESTAMP - 1, SYSTIMESTAMP - INTERVAL '1' DAY FROM DUAL;
输出:
SYSDATE-1 | SYSTIMESTAMP-1 | SYSTIMESTAMP-INTERVAL'1'DAY
:------------------ | :------------------ | :----------------------------------
2020-11-29 10:24:02 | 2020-11-29 10:24:02 | 2020-11-29 10:24:02.651735000+00:00
您可以看到,在中间列中,SYSTIMESTAMP-1
给出了与 SYSDATE-1
相同的输出,但在右侧列中,减去一个间隔确保了 TIMESTAMP WITH TIME ZONE
数据类型是维护。
所以你的查询:
SELECT * FROM user WHERE created_date < SYSTIMESTAMP-1
有效:
SELECT * FROM user WHERE created_date < CAST( SYSTIMESTAMP AS DATE )-1
它将具有完全相同的年、月、日、小时、分钟和(整数)秒组件,但会丢失 SYSTIMESTAMP
中的小数秒和时区信息。
如果您的列没有时区数据并且小数秒的精度水平对您来说无关紧要,那么您的查询就可以正常工作。
但是,如果您想保留时区 and/or 小数秒信息,那么您可以使用:
SELECT * FROM user WHERE created_date < SYSTIMESTAMP - INTERVAL '1' DAY;
但是,如果 created_date
是 DATE
列,您可能需要:
SELECT * FROM user WHERE created_date < SYSDATE - INTERVAL '1' DAY;
或
SELECT * FROM user WHERE created_date < SYSDATE - 1;
db<>fiddle here
我的 Oracle 数据库中有一列以下列格式记录用户的创建时间
30-NOV-20 11.49.11.000000000 AM
(TIMESTAMP(6) 格式)。
我想做的是 select 所有创建时间比当前时间早 24 小时的记录
所以我要做的是从当前时间减去 1 并进行比较。但是当我减去 1 时,它 returns 只有日期。
select * from user where created_date < SYSTIMESTAMP-1
dbms_output.put_line (SYSTIMESTAMP-1);
-->29-NOV-20
缺少时间部分,这让我无法与 table 中创建的时间进行比较 请帮我完成这个任务。
如果您从 date
数据类型(例如 sysdate
)中减去 1
,它会让您倒退一天。但是,如果您从 timestamp
数据类型值中减去它,Oracle 会将其转换为 date 和 return 日期(此外,它将被截断)。
参见以下示例:
SQL> select
2 systimestamp val1,
3 systimestamp - 1 val2,
4 --
5 systimestamp - interval '1' day val3
6 from dual;
VAL1
-----------------------------------------------------
VAL2
--------
VAL3
-----------------------------------------------------
30.11.20 09:55:01,439352 +01:00
29.11.20
29.11.20 09:55:01,439352000 +01:00
SQL>
所以,你应该做的是减去一个间隔,即
select *
from user
where created_date < systimestamp - interval '1' day;
您可以将其用作 (SYSDATE, -1)。 另外,如果要搜索24小时内的新记录,应该是"created_date> = (sysdate-1)".
一半的问题是,无论使用什么客户端程序来显示值,都使用 DD-MON-RR
.
您可以更改 NLS_DATE_FORMAT
和 NLS_TIMESTAMP_FORMAT
会话参数,这将(假设您的客户端程序使用它们而不是某些内部设置)为您提供您期望的输出:
ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';
ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF9';
ALTER SESSION SET NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF9TZR';
然后
SELECT SYSDATE, SYSTIMESTAMP FROM DUAL;
输出(取决于您的系统时区):
SYSDATE | SYSTIMESTAMP :------------------ | :---------------------------------- 2020-11-30 10:12:22 | 2020-11-30 10:12:22.476282000+00:00
如果您使用 SYSTIMESTAMP-1
,则 Oracle 不支持从 TIMESTAMP [WITH TIME ZONE]
数据类型中减去 NUMBER
数据类型,但它支持从中减去 NUMBER
数据类型DATE
数据类型并将执行从 TIMESTAMP
到 DATE
的隐式转换,以便查询有效。
例如:
SELECT SYSDATE - 1, SYSTIMESTAMP - 1, SYSTIMESTAMP - INTERVAL '1' DAY FROM DUAL;
输出:
SYSDATE-1 | SYSTIMESTAMP-1 | SYSTIMESTAMP-INTERVAL'1'DAY :------------------ | :------------------ | :---------------------------------- 2020-11-29 10:24:02 | 2020-11-29 10:24:02 | 2020-11-29 10:24:02.651735000+00:00
您可以看到,在中间列中,SYSTIMESTAMP-1
给出了与 SYSDATE-1
相同的输出,但在右侧列中,减去一个间隔确保了 TIMESTAMP WITH TIME ZONE
数据类型是维护。
所以你的查询:
SELECT * FROM user WHERE created_date < SYSTIMESTAMP-1
有效:
SELECT * FROM user WHERE created_date < CAST( SYSTIMESTAMP AS DATE )-1
它将具有完全相同的年、月、日、小时、分钟和(整数)秒组件,但会丢失 SYSTIMESTAMP
中的小数秒和时区信息。
如果您的列没有时区数据并且小数秒的精度水平对您来说无关紧要,那么您的查询就可以正常工作。
但是,如果您想保留时区 and/or 小数秒信息,那么您可以使用:
SELECT * FROM user WHERE created_date < SYSTIMESTAMP - INTERVAL '1' DAY;
但是,如果 created_date
是 DATE
列,您可能需要:
SELECT * FROM user WHERE created_date < SYSDATE - INTERVAL '1' DAY;
或
SELECT * FROM user WHERE created_date < SYSDATE - 1;
db<>fiddle here