我正在研究事件的重复应用程序。我有一个日期范围,比如2010年1月1日到2011年12月31日。我想有效地返回每个月的所有第3个星期四(任意)。我可以在代码中非常简单地做到这一点,需要注意的是必须在存储过程中完成。最终我想要的东西是:
CALL return_dates(event_id);
该event_id的start_date为1/1/2010,end_date为12/31/2011。结果集如下:
1/20/2010
2/14/2010
3/17/2010
4/16/2010
5/18/2010
etc.
我只是好奇最有效的方法是什么,考虑到我的实际用法可能会得到一个非常大的结果集。
答案 0 :(得分:1)
想到一个想法 - 您可以创建一个表并存储您感兴趣的日期。
答案 1 :(得分:0)
好的,我还没有对它进行测试,但我认为最有效的方法是通过一个计数表,无论如何都要在数据库中使用:
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之间。 该范围内的日期名称必须是唯一的,因此我们可以立即找到它。
如果您想要第二个日期名称,只需适当修改范围或使用参数进行计算。
它使用startdate建立一个日期表,然后添加天数(通过计数表中的数字列表),直到它到达结束日期。
希望它有所帮助!