【问题标题】:How to get 24 hours back time from current time in Oracle如何在 Oracle 中从当前时间返回 24 小时
【发布时间】:2021-03-12 03:56:17
【问题描述】:

我的 Oracle 数据库中有一个列,它以以下格式记录用户的创建时间 30-NOV-20 11.49.11.000000000 AM(TIMESTAMP(6) 格式)。 我想要做的是选择创建时间比当前时间早 24 小时的所有记录 所以我要做的是从当前时间减去 1 并进行比较。但是当我减去 1 时,它只返回日期。

select * from user where created_date < SYSTIMESTAMP-1

dbms_output.put_line (SYSTIMESTAMP-1);-->29-NOV-20

缺少时间部分,这使我无法与表中创建的时间进行比较 请帮我完成这项任务。

【问题讨论】:

    标签: sql oracle oracle11g timestamp


    【解决方案1】:

    如果你从 date 数据类型(例如 sysdate)中减去 1,它会让你后退一天。但是,如果您从 timestamp 数据类型值中减去它,Oracle 会将其转换为 date 并返回一个日期(此外,它会被截断)。

    看下面的例子:

    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;
    

    【讨论】:

    • 不会按照TRUNC函数截断;它只会丢失小数秒。时间戳的其余时间部分仍然存在。 OP 的 NLS(或 IDE)设置只是不显示时间组件。
    【解决方案2】:

    您可以将其用作 (SYSDATE, -1)。 另外,如果要在 24 小时内搜索新记录,则应为“created_date> = (sysdate-1)”。

    【讨论】:

      【解决方案3】:

      问题的一半是用于显示值的任何客户端程序都将default date format 用于其领土,并且默认格式设置为DD-MON-RR

      您可以更改 NLS_DATE_FORMATNLS_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;
      

      输出(取决于您的系统时区):

      日期 |系统时间戳 :----------------- | :------------------------------------ 2020-11-30 10:12:22 | 2020-11-30 10:12:22.476282000+00:00

      如果您使用 SYSTIMESTAMP-1,则 Oracle 不支持从 TIMESTAMP [WITH TIME ZONE] 数据类型中减去 NUMBER 数据类型,但它支持从 DATE 数据类型中减去 NUMBER 数据类型,并将执行从 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 的小数秒和时区信息。

      如果您的列没有时区数据,并且小数秒的精度级别对您来说并不重要,那么您的查询将充分发挥作用。

      但是,如果您想保留时区和/或小数秒信息,则可以使用:

      SELECT * FROM user WHERE created_date <  SYSTIMESTAMP - INTERVAL '1' DAY;
      

      但是,如果 created_dateDATE 列,您可能需要:

      SELECT * FROM user WHERE created_date <  SYSDATE - INTERVAL '1' DAY;
      

      SELECT * FROM user WHERE created_date <  SYSDATE - 1;
      

      db小提琴here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2012-09-14
        • 1970-01-01
        相关资源
        最近更新 更多