Obter o 1º e último dias do mês anterior em SQL

 
 
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)