Вопрос

Я работаю над рецидивом для событий. У меня есть диапазон дата скажем, 1 января 2010 года по 31 декабря 2011 года. Я хочу эффективно добраться до всех 3-го четверга (произвольных) каждого месяца. Я мог бы сделать это довольно тривиально в коде, будьте что это должен быть сделано в хранимой процедуре. В конечном итоге я бы хотел что-то вроде:

CALL return_dates(event_id);

Этот Event_ID имеет start_date 1/1/2010 и end_date от 01.01.2011. Набор результатов будет что-то вроде:

1/20/2010
2/14/2010
3/17/2010
4/16/2010
5/18/2010
etc. 

Мне просто любопытно, какой наиболее эффективный метод этого будет, учитывая, что я мог бы оказаться очень большим набором результатов в моем фактическом использовании.

Это было полезно?

Решение

Одна идея, которая приходит на ум - вы можете создать таблицу и хранить даты, которые вас там интересуют.

Другие советы

Хорошо, я не проверял это, но я думаю, что самый эффективный способ сделать это через подсчету таблицу, которая является полезной, чтобы иметь в БД в любом случае:

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 каждый месяц должен быть между 15 и 21-го инклюзивным. Дневные имена в этом диапазоне должны быть уникальными, поэтому мы можем найти его сразу.

Если вы хотите второе дневное значение, просто изменяйте диапазон соответствующим образом или используйте параметр для расчета его.

Он поучен к контуре даты, используя StartDate, а затем добавлять дни на (через список чисел в таблице подсветки) до тех пор, пока он не достигнет даты окончания.

Надеюсь, поможет!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top