【问题标题】:get the previous last date of the month in oracle sql在oracle sql中获取上个月的最后一个日期
【发布时间】:2018-01-18 09:04:26
【问题描述】:

我有以下查询,当该查询在当前月份运行时,该查询是当月的最后一个日期。但是由于我将在存储过程中使用此查询,并且此过程可能会在当前月份的 1 号或 2 号或 3 号运行,所以在这种情况下,我想每次都取上一个上个月的日期。例如,如果查询在 2 月 2 日或 3 日运行,那么它将返回 1 月 31 日的日期,即上个月的最后一个日期。

C_DATE 列是日期数据类型

Select * from C_LOG
WHERE C_DATE = LAST_DAY(to_date(sysdate,'YYYYMMDD'))-1

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    您可以使用EXTRACT( DAY FROM SYSDATE ) 获取当月的当前日期。如果这低于您的阈值,那么您可以获得上个月的最后一天,否则使用当月的最后一天:

    SELECT *
    FROM   C_LOG
    WHERE  C_DATE = CASE
                    WHEN EXTRACT( DAY FROM SYSDATE ) <= 3
                    THEN TRUNC( SYSDATE, 'MM' ) - INTERVAL '1' DAY
                    ELSE LAST_DAY( TRUNC( SYSDATE ) )
                    END
    

    注意

    不要使用to_date(sysdate,'YYYYMMDD'),因为TO_DATE( date_string, format_model ) 将字符串作为其第一个参数,因此Oracle 会将日期隐式转换为字符串;有效地做:

    TO_DATE(
      TO_CHAR(
        SYSDATE,
        ( SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT' )
      ),
      'YYYYMMDD'
    )
    

    如果NLS_DATE_FORMAT 不是YYYYMMDD,则查询将失败。由于这是一个会话参数,因此每个用户都可以随时更改它,对于更改该参数而不更改查询 sql 的任何用户,您的查询将失败。

    相反,如果您想删除 DATE 数据类型的时间部分,请使用 TRUNC 函数。

    【讨论】:

    • 例如,如果 2 月的月份小于 3,例如 2 月 3 日,那么此查询将采用上个月的最后一个日期,即 1 月 31 日。如果月份是 1 月本身,则这将需要日期的最后一个月,即 1 月 31 日,对吗?
    • @Andrew 如果当月的第一天、第二天或第三天,那么它将使用上个月的最后一天,否则它将使用当月的最后一天。
    • 谢谢,但我担心 NLS 设置,因为你提到它应该是 YYYYMMDD。因为我将在生产中部署我的程序,所以我不知道它是否有这个 NLS 设置 YYYYMMDD
    • @Andrew 然后不要依赖日期和字符串之间的隐式转换 - 我的回答显示了如何使用 TRUNC 删除时间组件,并且不依赖于将日期转换为字符串,因此不会遇到用户更改NLS_DATE_FORMAT 的任何问题。
    【解决方案2】:

    你可以使用 ADD_MONTHS 函数,

    SELECT ADD_MONTHS(LAST_DAY(SYSDATE), -1) FROM DUAL;
    

    你也可以使用 TRUNC 函数

    SELECT TRUNC(SYSDATE, 'MM')-1 FROM DUAL;
    

    【讨论】:

      【解决方案3】:

      另一种变化:

      SELECT *
        FROM c_log
       WHERE c_date =
                TRUNC (
                   LAST_DAY (
                      CASE
                         WHEN EXTRACT (DAY FROM SYSDATE) <= 3
                         THEN
                            ADD_MONTHS (SYSDATE, -1)
                         ELSE
                            SYSDATE
                      END));
      

      【讨论】:

      • 这个条件 WHEN EXTRACT (DAY FROM SYSDATE)
      • 返回天数;今天是 1 月 18 日,所以它会返回“18”。如果您更习惯它,它类似于 TO_CHAR(SYSDATE, 'DD') 返回的值。请注意,您必须将 TO_NUMBER 应用于字符串,否则您可能会得到意想不到的结果(例如,排序时“13”在“2”之前)。
      • 例如,如果 2 月的月份小于 3,例如 2 月 3 日,那么此查询将采用上个月的最后一个日期,即 1 月 31 日。如果月份是 1 月本身,则这将需要日期的最后一个月,即 1 月 31 日,对吗?如果 nls 设置不是格式,即 YYYYMMDD ,则此查询不会失败?
      • 对于第 1、2 和 3 天,它将返回上个月的最后一天。例如,如果是 1 月 2 日,它将返回 12 月 31 日。如果是 3 月 1 日,它将在 2 月 28 日(或 2 月 29 日,取决于闰年)返回。它不依赖于 NLS 设置。
      猜你喜欢
      • 2018-01-30
      • 2017-10-25
      • 2012-05-29
      • 1970-01-01
      • 2022-06-10
      • 2021-06-07
      • 2023-02-08
      • 2021-06-28
      • 1970-01-01
      相关资源
      最近更新 更多