3-е <день_файла> месяца - MySQL

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

CALL return_dates(event_id);

Этот event_id имеет начальную дату 01.01.2010 и конечную дату 31.12.2011. Результат будет примерно таким:

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

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

2 ответа

Решение

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

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

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

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

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

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

Другие вопросы по тегам