Tengo la consulta a continuación que toma la última fecha del mes cuando esta consulta se ejecuta en el mes actual. Pero como voy a usar esta consulta en un procedimiento almacenado y este procedimiento se ejecutará el 1 °, 2 ° o 3 ° del mes actual, en este caso quiero tomar la fecha del último mes cada vez. Por ejemplo, si la consulta se ejecuta el 2 o el 3 de febrero, devolverá la fecha con 31 de enero, que es la última fecha del mes anterior.

La columna C_DATE es el tipo de datos de fecha

Select * from C_LOG
WHERE C_DATE = LAST_DAY(to_date(sysdate,'YYYYMMDD'))-1
1
Andrew 18 ene. 2018 a las 12:04

3 respuestas

La mejor respuesta

Puede usar EXTRACT( DAY FROM SYSDATE ) para obtener el día actual del mes. Si está por debajo de su umbral, puede obtener el último día del mes anterior; de lo contrario, use el último día del mes actual:

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

Nota :

No utilice to_date(sysdate,'YYYYMMDD') ya que TO_DATE( date_string, format_model ) toma una cadena como primer argumento, por lo que Oracle implícitamente convertirá la fecha en una cadena; haciendo efectivamente:

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

Si NLS_DATE_FORMAT no es YYYYMMDD, la consulta fallará. Dado que este es un parámetro de sesión, cada usuario puede cambiarlo en cualquier momento y su consulta fallará para cualquier usuario que cambie ese parámetro sin cambiar nunca sql de la consulta.

En cambio, si desea eliminar el componente de tiempo de un tipo de datos DATE, use la función TRUNC.

5
MT0 18 ene. 2018 a las 09:15

Otra variación más:

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));
2
Littlefoot 18 ene. 2018 a las 09:18

Puedes usar la función ADD_MONTHS,

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

También puedes usar la función TRUNC

SELECT TRUNC(SYSDATE, 'MM')-1 FROM DUAL;
2
eifla001 18 ene. 2018 a las 09:14