2015-04-23 181 views
1

我有两个特定的日期。 可以说从2014-04-04到2015-10-04。 我有一个计划,说Blah课程将在周一,周三和周五。 现在我想从2014-04-04到2015-10-04获取每个星期一,星期三和星期五的日期。两个给定日期之间的搜索日期

回答

1

如果您没有数字表,则可以使用递归CTE。像这样的东西。请注意,DATEPART(weekday,Dates) IN(1,3,5)取决于您的设置SELECT @@DATEFIRST

例如如果@@DATEFIRST1然后使用DATEPART(weekday,Dates) IN(1,3,5)

DECLARE @StartDate DATETIME 
DECLARE @EndDate DATETIME 
SET @StartDate = '2014-04-04' 
SET @EndDate = '2015-10-04' 
;WITH CTE AS 
(
    SELECT @StartDate Dates 
    UNION ALL SELECT DATEADD(d,1,Dates) FROM CTE WHERE DATEADD(d,1,Dates) <[email protected] 
) 

SELECT Dates,DATENAME(weekday,Dates) FROM CTE 
WHERE DATEPART(weekday,Dates) IN(1,3,5) 
OPTION (MAXRECURSION 0); 
GO 
+0

消息139,级别15,状态1,行0 无法将默认值分配给本地变量。 消息139,级别15,状态1,行0 无法将默认值分配给本地变量。 消息137,级别15,状态2,行6 必须声明标量变量“@StartDate”。 消息137,级别15,状态2,行7 必须声明标量变量“@EndDate”。 – Shafay

+0

这些是您的查询中遇到的错误M – Shafay

+0

这很奇怪,sql server 2008支持'date'数据类型。尝试将其更改为'DATETIME' – ughai

2

任何经验丰富的SQL Server资深人员对此的标准答复将是创建日历表。但是这经常被人嘲笑。所以这里有一个缓慢和出的现成方法:

DECLARE @startDate DATE = '2014-04-04', @endDate DATE = '2015-10-04'; 

WITH CTE(N) AS (SELECT 1 FROM (VALUES(1),(1),(1),(1),(1),(1),(1),(1),(1),(1))a(N)), 
CTE2(N) AS (SELECT 1 FROM CTE x CROSS JOIN CTE y), 
CTE3(N) AS (SELECT 1 FROM CTE2 x CROSS JOIN CTE2 y), 
CTE4(N) AS (SELECT 1 FROM CTE3 x CROSS JOIN CTE3 y), 
CTE5(N) AS (SELECT 1 FROM CTE4 x CROSS JOIN CTE4 y), 
CTE6(N) AS (SELECT 0 UNION ALL 
      SELECT TOP (DATEDIFF(day,@startDate,@endDate)) 
      ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) 
      FROM CTE5), 
TALLY(N) AS (SELECT DATEADD(day, N, @startDate) 
      FROM CTE6 
      WHERE DATENAME(weekday,DATEADD(day, N, @startDate)) IN ('Monday','Tuesday','Wednesday')) 
SELECT N 
FROM TALLY 
ORDER BY N; 
+0

您能否定义这一点。 – Shafay

+0

请原谅我的无知。 'define'是什么意思? –

+0

它给出了以下错误。 – Shafay

4

与日历表很简单:

SELECT t.* 
FROM dbo.TableName t 
INNER JOIN CalendarTable c 
    ON t.DateColumn = c.Date 
WHERE c.Date between '2014-04-04' AND '2015-10-04' 
AND DATEPART(dw, c.Date) IN (1,3,5) 

How to generate a calendar table(寻找“万年历表”)。

+0

我没有日期表。 只是一个批次表,其中有一列日期从一列日期到 – Shafay

+1

@Shafay:创建一个好时机?!正如文章中提到的,30年的日期只有136KB的硬盘空间。 –

+0

@TimSchmelter请参阅?像往常一样嘲笑! –

0

DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME SET @StartDate = '2014年4月4日' SET @EndDate =“2015-10 -04'

; WITH CTE AS ( SELECT @StartDate日期 UNION ALL SELECT DATEADD(d,1,日期)FROM CTE WHERE DATEADD(d,1,日期)< = @结束日期 )

选择日期,DATENAME(星期,日期)FROM CTE WHERE DATEPART(星期,日期)IN(1,3,5) OPTION(MAXRECURSION 0); GO

---感谢@ughai

+0

你不需要重新回答。如果答案对您有帮助,您只需要将答案标记为已接受。你可以投票所有帮助你的答案。 – ughai

0

我和另一种方式来做到这一点川方。 此查询不仅会显示日期之间的日期,但它也会比较你想比较的日期。

Q.日期比较

DECLARE @StartDate DATETIME DECLARE @EndDate DATETIME SET @StartDate = '2014年12月22日' SET @EndDate = '2015年2月13日'

降表#TabCourseDetailID SELECT ROW_NUMBER ()OVER(ORDER BY CourseDetailID ASC)AS行, CourseDetailID 成#TabCourseDetailID
从coursedetail 其中UNITTYPE = 'T' 和courseID = 1

声明@counter为INT 申报@CourseDetailID VARCHAR(500) 组@counter = 0

声明@TempTable表(FirstValue日期时间,LastValue INT)

而@StartDate < = @EndDate 开始 如果DATEPART(星期,@开始日期)IN(2,4,6) begin

  Set @Counter = @counter+1 

      Select @CoursedetailId=CoursedetailId 
       from #TabCourseDetailID 
      where [email protected] 

      insert into @TempTable (FirstValue,LastValue) 
      values     (@StartDate,@CoursedetailId) 

     end 
set @StartDate =DATEADD(d,1,@StartDate) 
end 




select t.LastValue, 
     t.FirstValue, 
     bp.conductedDate 
from batchprogress bp 
Join @TempTable t on (t.LastValue=bp.CoursedetailID) 
where CourseID =1 and batchID =5 
order by t.lastvalue 
相关问题