I prefer a calendar table for this type of query. In fact, I prefer to use a calendar table over date functions for most queries. Here is minimal. I use more columns and more rows in production. (100 years of data - only 37 thousand lines).
create table calendar ( cal_date date not null primary key, day_of_week varchar(15) ); insert into calendar (cal_date) values ('2015-01-01'), ('2015-01-02'), ('2015-01-03'), ('2015-01-04'), ('2015-01-05'), ('2015-01-06'), ('2015-01-07'), ('2015-01-08'), ('2015-01-09'), ('2015-01-10'), ('2015-01-11'), ('2015-01-12'), ('2015-01-13'), ('2015-01-14'), ('2015-01-15'), ('2015-01-16'), ('2015-01-17'), ('2015-01-18'), ('2015-01-19'), ('2015-01-20'), ('2015-01-21'), ('2015-01-22'), ('2015-01-23'), ('2015-01-24'), ('2015-01-25'), ('2015-01-26'), ('2015-01-27'), ('2015-01-28'), ('2015-01-29'), ('2015-01-30'), ('2015-01-31'), ('2015-02-01'), ('2015-02-02'), ('2015-02-03'), ('2015-02-04'), ('2015-02-05'), ('2015-02-06'), ('2015-02-07'), ('2015-02-08'), ('2015-02-09'), ('2015-02-10'), ('2015-02-11'), ('2015-02-12'), ('2015-02-13'), ('2015-02-14'), ('2015-02-15'), ('2015-02-16'), ('2015-02-17'), ('2015-02-18'), ('2015-02-19'), ('2015-02-20'), ('2015-02-21'), ('2015-02-22'), ('2015-02-23'), ('2015-02-24'), ('2015-02-25'), ('2015-02-26'), ('2015-02-27'), ('2015-02-28') ; update calendar set day_of_week = datename(weekday, cal_date); alter table calendar alter column day_of_week varchar(15) not null; alter table calendar add constraint cal_date_matches_dow check (datename(weekday, cal_date) = day_of_week); create index day_of_week_ix on calendar (day_of_week);
Set privileges so that
- everyone can choose but
- almost no one can insert new lines, and
- even fewer people can delete lines.
(Or write a constraint that can guarantee no spaces. I think you can do it in SQL Server.)
You can select the next four Mondays after today with a very simple SQL statement. (The current date is 2015-01-05, which is Monday.)
select top 4 cal_date from calendar where cal_date > convert(date, getdate()) and day_of_week = 'Monday' order by cal_date;
CAL_DATE
-
2015-01-12
2015-01-19
2015-01-26
2015-02-02
This is a huge advantage for me. No procedural code. Simple SQL, which is obviously right. Big win.