以下是我的工作方式。這應該適用於任何版本的SQL Server。
需要注意的一件重要事情:首先,應該始終建立一個代表'現在'的單一值,即當前時刻。如果您現在在查詢中沒有一致的值,那麼當您的查詢執行時,您最終會得到一點信息,以便它在飛行中跨越日期邊界。沒有人願意爲他們上個月已經支付的東西記賬。最糟的是,邊緣的情況下盲蝽象是很難趕上,無論是開發商還是由QA,因爲無論是可能的工作,比方說,在11:59於12月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
謝謝尼古拉斯!我知道這看起來很奇怪,但由於我對基本SQL有一點基本的瞭解,所以時間/日期很痛苦!這是我找到的最佳MTD答案! +1給你!我肯定會在我的數據庫課堂上分享這些內容。 –
在兩者之間要小心,最好做
SQLMenace
@SQLMenace:'x between y和z'與'x> = y和x <= z'完全相同。無論數據類型如何,都沒有區別。你還會注意到我在這裏使用的是DateTime而不是DateTime2:如果我使用的是Datetime2,我會將上限調整到適當的100ns的界限。 ''之間''使得代碼更乾淨,更易讀。但謝謝你的建議。 –