I need to check whether a given date is in the preceding month for a monthly query. I can get
CURRENT DATE - 1 MONTH
to compare the selected date with, but I can't assume the current date will be the first day of each month exactly. Is there a built in way to get the first day of the month without extracting the year and month and gluing it back together?
First day of this year:
date('0001-01-01') + year(current date) years - 1 year
First day of this month:
date('0001-01-01') + year(current date) years - 1 year + month(current date) months - 1 month
First day of last month:
date('0001-01-01') + year(current date) years - 1 year + month(current date) months - 2 months
If you don't need to maintain SQL compatibility with Db2 LUW v10.5 and older, you can also use these convenient Db2 LUW v11.1 scalar functions: THIS_WEEK()
THIS_MONTH()
THIS_QUARTER()
and THIS_YEAR()
.
First day of this month:
THIS_MONTH(CURRENT DATE)
First day of last month:
THIS_MONTH(CURRENT DATE) - 1 MONTH
Last day of last month:
THIS_MONTH(CURRENT DATE) - 1 DAY
ROUND_TIMESTAMP()
ROUND_TIMESTAMP()
is available in Db2 9.7 and newer, but given that it by design rounds some input values down and others up, ROUND_TIMESTAMP()
is not an ideal way to reliably return the first day of the current month or previous month.
As pointed out in the original question, CURRENT DATE - 1 MONTH
will only return the first day of the previous month (the desired result) when run on the first day of the month, but ROUND_TIMESTAMP(CURRENT DATE - 1 MONTH, 'W')
only extends that behavior for three more days, until the fifth, when it will start returning the eighth day of the previous month. Similarly, ROUND_TIMESTAMP(CURRENT DATE - 1 MONTH, 'MM')
will only return the first day of the previous month up to and including the 15th, after which it will round upward and return the first day of the current month.