检查两个日期是否包含给定月份

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)

Eri*_*ier 5

我知道您正在寻找一种方法来选择任何一年中与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)


Jef*_*ffO 2

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)