If you get yourself a calendar table and you have a very simple query on your hands `
SELECT TOP 1 Date
FROM Calendar
WHERE IsWeekday = 1
AND Date >= @StartDate
AND Date <= @EndDate
ORDER BY NEWID();
You could always generate the dates on the fly though:
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();
Here the calendar CTE cross joins 3 table valued constructors to generate a maximum of 1,000 rows (10 x 10 x 10), then limits that to the number of days required using
TOP (DATEDIFF(DAY, @Start, @End) + 1)
Then generates a list of dates onward from the start by using ROW_NUMBER()
to generate values from 1 to n. So the basic element is:
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
Which gives:
Date
------------
2016-02-07
2016-02-08
2016-02-09
2016-02-10
2016-02-11
2016-02-12
2016-02-13
It is then a simple case of removing weekends with WHERE DATEPART(WEEKDAY, Date) NOT IN (6, 7)
and selecting a random row with TOP 1 ... ORDER BY NEWID()
. As as aside, when using something setting sensitive like DATEPART(WEEKDAY, ...)
you should always explicitly set the value you need rather than relying on defaults.
I may have misunderstood your requirements though, this last step is not necessary if you just want a list of all the dates