Хорошо, я не проверял это, но я думаю, что наиболее эффективный способ сделать это - использовать таблицу подсчета, которую в любом случае полезно иметь в БД:
IF EXISTS (SELECT * FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[num_seq]') AND type in (N'U'))
DROP TABLE [dbo].[num_seq];
SELECT TOP 100000 IDENTITY(int,1,1) AS n
INTO num_seq
FROM MASTER..spt_values a, MASTER..spt_values b;
CREATE UNIQUE CLUSTERED INDEX idx_1 ON num_seq(n);
Затем вы можете использовать это для создания диапазона дат между двумя датами. Это быстро, потому что он просто использует индекс (на самом деле часто быстрее, чем цикл, поэтому я верю)
create procedure getDates
@eventId int
AS
begin
declare @startdate datetime
declare @enddate datetime
--- get the start and end date, plus the start of the month with the start date in
select @startdate=startdate,
@enddate=enddate
from events where eventId=@eventId
select
@startdate+n AS date,
from
dbo.num_seq tally
where
tally.n<datediff(@monthstart, @enddate) and
Datepart(dd,@startdate+n) between 15 and 21 and
Datepart(dw, @startdate+n) = '<day>'
Помимо получения даты начала и окончания, третий x id каждого месяца должен быть между 15 и 21 числом включительно. Названия дней в этом диапазоне должны быть уникальными, чтобы мы могли сразу их найти.
Если вам нужно второе имя дня, просто измените диапазон соответствующим образом или используйте параметр для его расчета.
Он создает таблицу дат, используя дату начала, а затем добавляя дни (через список чисел в таблице подсчета), пока не будет достигнута дата окончания.
Надеюсь, поможет!
person
mr_miles
schedule
01.09.2010