1

我正在开发事件的重复应用程序。我的日期范围是 2010 年 1 月 1 日到 2011 年 12 月 31 日。我想有效地返回每个月的所有第三个星期四(任意)。我可以在代码中非常简单地做到这一点,但需要注意的是它必须在存储过程中完成。最终我想要类似的东西:

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. 

我只是好奇这样做最有效的方法是什么,考虑到我在实际使用中可能会得到一个非常大的结果集。

4

2 回答 2

1

想到的一个想法 - 您可以创建一个表格并在那里存储您感兴趣的日期。

于 2010-08-30T16:13:30.900 回答
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 构造一个日期表,然后添加天数(通过计数表中的数字列表)直到它到达结束日期。

希望能帮助到你!

于 2010-09-01T20:02:25.447 回答