3-й месяца - mysql
-
25-09-2019 - |
Вопрос
Я работаю над рецидивом для событий. У меня есть диапазон дата скажем, 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, а затем добавлять дни на (через список чисел в таблице подсветки) до тех пор, пока он не достигнет даты окончания.
Надеюсь, поможет!