Вот как я это делаю. Это должно работать практически на любой версии SQL Server.
Одна важная вещь, на которую следует обратить внимание: вначале всегда следует устанавливать одно значение, представляющее «сейчас», текущий момент времени. Если в вашем запросе пока нет согласованного значения, вы в конечном итоге получите бит, когда ваш запрос будет выполнен так, что он пересекает границу даты во время полета. Нет ничего лучше, чем выставлять счета кому-то за то, за что они уже заплатили в прошлом месяце. Наихудшие, подобные крайним, ошибки трудно уловить ни разработчикам, ни QA, поскольку ни одна из них, вероятно, не будет работать, скажем, в 11:59 31 декабря.
Код:
declare
@dtNow datetime ,
@Today datetime ,
@dtFrom datetime ,
@dtThru datetime
---------------------------------------------------------------------------------------
-- set our effective notion of 'now'-ness.
--
-- We need have a consistent notion of now, lest we get bit in the a$$
-- by an edge case where we cross a day/month/year boundary in mid-execution.
--
-- NOTE: Mostly, we're interested in the *DATE* rather than the actual moment-in-time.
-- So, we carry around two flavors here.
---------------------------------------------------------------------------------------
set @dtNow = current_timestamp
set @Today = convert(datetime,convert(varchar,@dtNow,112),112)
---------------------------------------------------------------------------------------
-- compute the current date.
--
-- 1. get the current date sans timestamp (effectively start-of-day)
-- 2. add 1 day, then back off 3 millseconds to set it to the last tick of the current day
--
-- NOTE: Depending on the requirements of your particular application (and the nature
-- of your data), you might want to use the actual current date/time value as
-- your upper bound.
--
-- FURTHER NOTE: How far to back off is dependent on your date/time type:
--
-- * For DateTime, the resolution is milliseconds and the last tick of the day
-- is 997 milliseconds, so you need to back off 3ms from the start of the
-- next day.
--
-- * SmallDateTime has a 1 second resolution. The last tick of the day, natch,
-- is 59 seconds, so you need to back off 1 second from the start of the next day.
--
-- * For DateTime2, the user declares the precision in decimal fractions of a second,
-- though its resolution is 100ns ticks. You'll need (especially if you're working
-- with DateTime2 columns/variables of differing precision) experiment to figure out
-- what traps Microsoft has set for you inside DateTime2 and what you need to do to
-- make things work properly.
--
---------------------------------------------------------------------------------------
set @dtThru = dateadd(ms,-3,dateadd(day,1,@Today))
--set @dtThru = @dtNow -- if you need the actual current date/time value
---------------------------------------------------------------------------------------
-- compute start of month
--
-- We do this by subtracting the day number of 'today' from the date/time value @today.
-- That gives us the last day of the prior month. Then we add one day to get the first
-- day of the current month.
---------------------------------------------------------------------------------------
set @dtFrom = dateadd(day,1-day(@Today),@Today)
---------------------------------------------------------------------------------------
-- finally, make your query for 'current month to date'
---------------------------------------------------------------------------------------
select *
from dbo.foobar t
where t.recorded_date between @dtFrom and @dtThru