我在下面的查询中查询了当前月份运行此查询的月份的最后一个日期。但是因为我将在存储过程中使用此查询,并且此过程将在当前月份的1日或2日或3日运行,然后在这种情况下,我希望每次都使用上个月的上个月日期。例如,如果查询在2月2日或3月运行,那么它将返回1月31日的日期,即上个月的上个月。
C_DATE
列是日期数据类型
Select * from C_LOG
WHERE C_DATE = LAST_DAY(to_date(sysdate,'YYYYMMDD'))-1
答案 0 :(得分:4)
您可以使用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
函数。
答案 1 :(得分:2)
你可以使用ADD_MONTHS函数,
SELECT ADD_MONTHS(LAST_DAY(SYSDATE), -1) FROM DUAL;
您也可以使用TRUNC功能
SELECT TRUNC(SYSDATE, 'MM')-1 FROM DUAL;
答案 2 :(得分:2)
另一种变化:
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));