Como obter o 1º dia do mês anterior:
select dateadd(mm,-1,dateadd(dd,-day(getdate())+1,getdate()))
Como obter o último dia do mês anterior:
select dateadd(dd,-day(getdate()),getdate())
Neste exemplos usamos como data de referencia a data actual, para obter em relação a outra data basta substituir o getdate() pela da em relação à qual pretendemos obter o 1º e últimos dias dos mês anterior.
A forma apresentada é bastante condensada e funciona bem quando queremos sempre em relação ao mês anterior. Mas se quisermos para o mês corrente ou para o próximo mês já não é útil.
Mas fazendo alguma abstração podemos chegar a 2 funções, não tão eficientes diga-se, mas que nos permite obter o 1º e último dias de qualquer data relativa:
CREATE FUNCTION fnFirstDayOfRelativeMonth
(
@CurrentDate datetime = null,
@RelativeMonth int = -1
)
RETURNS dateTime
AS
BEGIN
declare @ReturnDate datetime
if(@CurrentDate is null)
begin
set @CurrentDate = getdate()
end
set @ReturnDate = dateadd(mm,@RelativeMonth,dateadd(dd,-day(@CurrentDate)+1,@CurrentDate))
RETURN @ReturnDate
END
GO
CREATE FUNCTION fnLastDayOfRelativeMonth
(
@CurrentDate DateTime = null,
@RelativeMonth int = 0
)
RETURNS datetime
AS
BEGIN
declare @ReturnDate datetime
if(@CurrentDate is null)
begin
set @CurrentDate = getdate()
end
set @ReturnDate = dateadd(dd,-day(@CurrentDate),dateadd(mm,@RelativeMonth+1,@CurrentDate))
RETURN @ReturnDate
END
GO
A utilização é bastante simples: no 1º parâmetro é data, se for a NULL assume a data corrente; o 2º parâmetro é o mês relativo, em que negativos é para meses anteriores, 0 (zero) é para o mês da data indicada e positivos é para meses posteriores à data indicada:
select [dbo].[fnFirstDayOfRelativeMonth](null,-1)
select [dbo].[fnLastDayOfRelativeMonth](null,-1)
select [dbo].[fnFirstDayOfRelativeMonth](‘2012-02-15’,0)
select [dbo].[fnLastDayOfRelativeMonth](‘2012-02-15’,0)
select [dbo].[fnFirstDayOfRelativeMonth](null,+1)
select [dbo].[fnLastDayOfRelativeMonth](null,+1)