我有以下查询,该查询采用当月运行此查询的月份的最后一天。但是由于我将在存储过程中使用此查询,并且此过程可能会在当前月份的 1 号、第 2 号或 3 号运行,那么在这种情况下,我想每次都采用上个月的日期。例如,如果查询在 2 月 2 日或 3 日运行,则它将返回 1 月 31 日的日期,即上个月的最后一个日期。
C_DATE
列是日期数据类型
Select * from C_LOG
WHERE C_DATE = LAST_DAY(to_date(sysdate,'YYYYMMDD'))-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'
)
如果未YYYYMMDD
NLS_DATE_FORMAT
,则查询将失败。由于这是一个会话参数,因此每个用户都可以随时更改它,对于更改该参数而不更改查询 sql 的任何用户,查询都将失败。
相反,如果要删除DATE
数据类型的时间部分,请使用 TRUNC
函数。
你可以使用ADD_MONTHS函数,
SELECT ADD_MONTHS(LAST_DAY(SYSDATE), -1) FROM DUAL;
您也可以使用 TRUNC 功能
SELECT TRUNC(SYSDATE, 'MM')-1 FROM DUAL;
另一种变体:
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));