Sal*_*n A 5 sql sql-server datetime date
我的问题很简单......或者可能不是.我有一个包含两个日期的表:
StartDate
EndDate
Run Code Online (Sandbox Code Playgroud)
我有一个月的常数.例如:
DECLARE @MonthCode AS INT
SELECT @MonthCode = 11 /* NOVEMBER */
Run Code Online (Sandbox Code Playgroud)
我需要一个SINGLE QUERY来查找StartDate和EndDate包含给定月份的所有记录.例如:
/* Case 1 */ Aug/10/2009 - Jan/01/2010
/* Case 2 */ Aug/10/2009 - Nov/15/2009
/* Case 3 */ Nov/15/2009 - Jan/01/2010
/* Case 4 */ Nov/15/2009 - Nov/15/2009
/* Case 5 */ Oct/01/2010 - Dec/31/2010
Run Code Online (Sandbox Code Playgroud)
第一个也是最后一个案例需要特别注意:两个日期都在十一月之外但是跨越它.
以下查询不处理案例1和5:
WHERE MONTH( StartDate ) = @MonthCode OR MONTH( EndDate ) = @MonthCode
Run Code Online (Sandbox Code Playgroud)
以下查询也失败,因为Aug <Nov AND Nov <Jan = false:
WHERE MONTH( StartDate ) = @MonthCode OR MONTH( EndDate ) = @MonthCode OR (
MONTH( StartDate ) < @MonthCode AND @MonthCode < MONTH( EndDate )
)
Run Code Online (Sandbox Code Playgroud)
我知道您正在寻找一种方法来选择任何一年中与11月相交的所有范围.
这是逻辑:
如果范围是一年(例如2009年),则开始月份必须等于或等于11月和11月之后或等于11月的结束月份
如果范围落在随后的两年(例如2009-2010),则开始月份必须等于11月或等于11月或等于11月的结束月份
如果范围为两年且差异超过1年(例如2008-2010),则11月总是包含在范围内(此处为2009年11月)
以伪代码翻译,条件是:
// first case
(
(YEAR(StartDate)=YEAR(EndDate)) AND
(MONTH(StartDate)<=MonthCode AND MONTH(EndDate)>=MonthCode)
)
OR
// second case
(
(YEAR(EndDate)-YEAR(StartDate)=1) AND
(MONTH(StartDate)<=MonthCode OR MONTH(EndDate)>=MonthCode)
)
OR
// third case
(
YEAR(EndDate)-YEAR(StartDate)>1
)
Run Code Online (Sandbox Code Playgroud)
DECLARE @MonthCode AS INT
SELECT @MonthCode = 11 /* NOVEMBER */
declare @yourtable table(
startdate datetime
, enddate datetime
)
insert into @yourtable(
startdate
, enddate
)
(
select '8/10/2009', '01/01/2010'
union all
select '8/10/2009' , '11/15/2009'
union all
select '11/15/2009' , '01/01/2010'
union all
select '11/15/2009' , '11/15/2009'
union all
select '10/01/2010' , '12/31/2010'
union all
select '05/01/2009', '10/30/2009'
)
select *
from @yourtable
where DateDiff(mm, startdate, enddate) > @MonthCode -- can't go over 11 months without crossing date
OR (Month(startdate) <= @MonthCode -- before Month selected
AND (month(enddate) >=@MonthCode -- after month selected
OR year(enddate) > year(startdate) -- or crosses into next year
)
)
OR (Month(startdate) >= @MonthCode -- starts after in same year after month
and month(enddate) >= @MonthCode -- must end on/after same month assume next year
and year(enddate) > year(startdate)
)
Run Code Online (Sandbox Code Playgroud)