Think about the logic "imperatively" first.
if todays date is the first of the month then
the query range is from the first of last month until the the end of last month
else
the query range is from the start of the current month until today
Now start turning it into TSQL... (this will work regardless of whether your table stores the dates as date
or datetime
).
-- today
declare @today as date = getdate() -- implicit cast to date will remove time component
--if today's date is the first of the month
if (datepart(day, @today) = 1)
-- from the first of last month:
>= dateadd(month, -1, @today)
-- until the the end of last month
< @today
-- else from the start of the current month...
>= datefromparts(year(@today), month(@today), 1)
-- until the end of today, which is the same as "before tomorrow"
< dateadd(day, 1, @today)
Put it all together!
declare @today date = getdate();
declare @startDate date = iif(
datepart(day, @today) = 1,
dateadd(month, -1, @today),
datefromparts(year(@today), month(@today), 1)
);
declare @endDate date = iif(
datepart(day, @today) = 1,
@today,
dateadd(day, 1, @today)
);
select ... where theDate >= @startDate and theDate < @endDate;