如果你给自己一个calendar table 并且你有一个非常简单的查询`
SELECT TOP 1 Date
FROM Calendar
WHERE IsWeekday = 1
AND Date >= @StartDate
AND Date <= @EndDate
ORDER BY NEWID();
不过,您总是可以即时生成日期:
SET DATEFIRST 1;
DECLARE @Start DATE = '20160207',
@End DATE = '20160214';
WITH Calendar (Date) AS
( SELECT TOP (DATEDIFF(DAY, @Start, @End) + 1)
DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY N1.N) - 1, @Start)
FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n1 (N)
CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n2 (N)
CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n3 (N)
)
SELECT TOP 1 Date
FROM Calendar
WHERE DATEPART(WEEKDAY, Date) NOT IN (6, 7)
ORDER BY NEWID();
此处日历 CTE 交叉连接 3 个表值构造函数以生成最多 1,000 行 (10 x 10 x 10),然后将其限制为使用所需的天数
TOP (DATEDIFF(DAY, @Start, @End) + 1)
然后使用ROW_NUMBER() 生成从一开始的日期列表以生成从1 到n 的值。所以基本元素是:
DECLARE @Start DATE = '20160207',
@End DATE = '20160214';
WITH Calendar (Date) AS
( SELECT TOP (DATEDIFF(DAY, @Start, @End) + 1)
DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY N1.N) - 1, @Start)
FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n1 (N)
CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n2 (N)
CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n3 (N)
)
SELECT Date
FROM Calendar
这给出了:
Date
------------
2016-02-07
2016-02-08
2016-02-09
2016-02-10
2016-02-11
2016-02-12
2016-02-13
这是一个简单的例子,用WHERE DATEPART(WEEKDAY, Date) NOT IN (6, 7) 删除周末并用TOP 1 ... ORDER BY NEWID() 选择一个随机行。顺便说一句,当使用像 DATEPART(WEEKDAY, ...) 这样敏感的设置时,您应该始终明确设置您需要的值,而不是依赖默认值。
不过,我可能误解了您的要求,如果您只想要所有日期的列表,则不需要最后一步