1

私はイベントの再発アプリケーションに取り組んでいます。たとえば、2010年1月1日から2011年12月31日までの日付範囲があります。毎月第3木曜日(任意)のすべてを効率的に返したいと思います。これはコードで非常に簡単に行うことができますが、注意点は、ストアドプロシージャで行う必要があるということです。最終的に私は次のようなものが欲しいです:

CALL return_dates(event_id);

そのevent_idのstart_dateは2010年1月1日、end_dateは2011年12月31日です。結果セットは次のようになります。

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

実際の使用で非常に大きな結果セットになる可能性があることを考えると、これを行うための最も効率的な方法が何であるかを知りたいだけです。

4

2 に答える 2

1

頭に浮かぶアイデアの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);

次に、これを使用して、2つの日付の間の日付範囲を構築できます。インデックスを使用するだけなので高速です(実際、ループよりも高速であることが多いので、信じられます)

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>'

開始日と終了日を取得する以外に、毎月3番目のxidは15日から21日までの間にある必要があります。その範囲の曜日の名前は一意である必要があるため、すぐに見つけることができます。

2番目の曜日名が必要な場合は、範囲を適切に変更するか、パラメーターを使用して計算します。

開始日を使用して日付テーブルを作成し、終了日になるまで(集計テーブルの数値のリストを介して)日を追加します。

それが役に立てば幸い!

于 2010-09-01T20:02:25.447 に答える