SQL Serverを使用して特定の日付に特定の日、年、月、週を追加

私は1つのクエリで立ち往生しています。君の力が必要。

私はテーブルtblEventCalendarEventsを持っています

id    name      start_date   end_date    rec_type
891 Bob Lehman  2012-05-01   2099-02-01  0_2_1_1
892 Bob Lehman  2012-11-01   2099-02-01  1_4_3_1
893 Bob Lehman  2012-05-03   2099-02-01  0_0_2_2

私はそのような仕事をしたい。私は今日も startdateとenddate の間にrecタイプに基づいているようなレコードを望みます。

RecTypeで記録された値は、 0_2_1_1 のようなストアです。このイベントは、2か月、1週間、3日ごとに繰り返されます。

2012-05-05のイベント開始が2012年1月1日を意味するので、このような繰り返しのイベントが2か月ごとに繰り返されるような日にイベントが繰り返されると、来月は7月、第1週、繰り返しの日付は2012年7月3日〜2012年7月3日です。

それで、

2012/07/01
2012/09/02
2012/11/04
2013/01/06
2
nl ru de
@JonathanLeffler今rec_typeフィールドで今すぐデータを(year_month_week_day)のようにデータをこのように繰り返すことを意味する私の質問を再度チェックしてください。 rec_typeが0_2_1_1の場合、出力データは2か月、第1週、第1日ごとに繰り返されます
追加された 著者 AB Vyas,
@techdoそうだけど、最後の議論では、その日の曜日の日ではないので、日曜日が1日、月曜日が2日、月曜日が2日、土曜日が平均7日というようなものです。
追加された 著者 AB Vyas,
@ Rajはい兄弟...
追加された 著者 AB Vyas,
@Rajはいこのテーブルは1kレコード以上です。毎日すべてのレコードを処理しなければならない
追加された 著者 AB Vyas,
これは、あなたが使用しているDBMSにかかわらず、ひどく混乱することになります。それはできます。それは楽しいことではありません。単に month_n_w_d_#no という表記を解析するのは面倒です。 year_n_x_y_#no バージョン(x番目の月とy番目の月のnth年ごと)でフィールドの意味が明確ではありません。あなたの質問は、 'created_date'列と 'updated_date'列を質問には重要ではないので便利に省略でき、水平スクロールバー(重要な列を隠す)を避けることができます。おそらく 'url'カラムも省略することができます。
追加された 著者 Jonathan Leffler,
あなたの質問は、「今日はレコードタイプに基づいて、開始日と終了日の間にあるレコードを欲しいですか?両方の条件が満たされていれば、タスクが発生しなければならないことを意味しますか?
追加された 著者 Raj,
このテーブルの大きさはどれくらいですか?私は推測している、毎日すべてのレコードを処理しなければならないのだろうか?
追加された 著者 Raj,
0_2_1_1 の場合は、2か月、最初の1週間、1日ごとの権利を意味しますか?したがって、あなたの例では、 2012/07/012012/09/01 などはありませんか?
追加された 著者 TechDo,

2 答え

最後に私は答えを得た。

USE [Database]
GO
/****** Object:  UserDefinedFunction [dbo].[getNextDay]    Script Date: 12/28/2012 17:10:19 ******/

SET ANSI_NULLS ON

GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[getNextDay](@SDate datetime, @Rec varchar(max))
returns datetime
as
BEGIN
--Find the next day based on Condition


Declare @SecArg varchar(max)
Declare @NYear varchar(max)
Declare @NMonth varchar(max)
Declare @NWeek varchar(max)
Declare @NDay varchar(max)

select @NYear = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

select @NMonth = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

select @NWeek = substring(@rec,0,CHARINDEX('_',@rec)) 

SET @REC = SUBSTRING(@rec,CHARINDEX('_',@rec)+1,LEN(@REC))

Declare @NewDate datetime
set @NewDate = @SDate
if (@NYear != 0 or @NYear != '')
begin

    set @SDate = DateAdd(Year,Convert(int,@Nyear),@SDate)
end


if (@NMonth != 0 or @NMonth != '')
begin
    set @SDate = DateAdd(Month,Convert(int,@NMonth),@SDate)
end

    return Convert(varchar, dbo.getWeekDay(Convert(int,@NWeek),Convert(Int,@rec),DATEADD(dd,-(DAY(@SDate)-1),@SDate)),120)
end

今私は特定の月の特定の週の日を見つけるために、別の関数getWeekDayを作成しました

USE [Database]
GO
/****** Object:  UserDefinedFunction [dbo].[getWeekDay]    Script Date: 12/28/2012 17:15:35 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE function [dbo].[getWeekDay]( @var_weeknum int, @var_weekday int, @var_date datetime)
returns datetime
as
BEGIN
     declare @cnt int
     declare @startDay int
     declare @DayDiffrence int 
     declare @ReturnDate datetime
     set @cnt = 1
     set @startday =  datepart(dw, dateadd(mm, datediff(mm, 0, @var_Date),0))
     set @DayDiffrence = @var_weekday - @startday
     set @ReturnDate = dateadd(mm, datediff(mm, 0, @var_date),0)

     if(@DayDiffrence > 0)
     begin
              set @ReturnDate = dateadd(d,@DayDiffrence,@ReturnDate)
              set @ReturnDate = dateadd(wk,@var_weeknum - 1,@ReturnDate)
     end
     else
     begin
              set @ReturnDate = dateadd(d,7 - (@DayDiffrence * -1),@ReturnDate)
              set @ReturnDate = dateadd(wk,@var_weeknum - 1,@ReturnDate)
     end

             return @ReturnDate
    end

さて、私はちょうど単一のクエリで私の答えを得ました

 select dbo.getNextDay('2012-07-01','0_2_3_3')

 In this my date is 2012-07-01 
 my condition is every 0 year, 2 month, and 3rd week and 3rd dayofweek.

 so this will return 2012-09-18

www.google.comblog.sqlauthority.com また、私のStackoverflowのおかげで.... .... :)

2
追加された

まず、rec_typeフィールドのテーブルをvarcharにするのではなく、再構成(正規化)することを強くお勧めします。4つのtinyintフィールドは次のようになります。 rec_y rec_m rec_w rec_d

そして、次のようにユーザー定義関数を書くだけです:

CREATE FUNCTION GetNextEvent 
(
    @curevent datetime, @rec_y tinyint, @rec_m tinyint, @rec_w tinyint, @rec_d tinyint, @end_date datetime
)
RETURNS datetime AS
BEGIN
    DECLARE @nextevent datetime
    set @nextevent=DATEADD(DAY,@rec_d,DATEADD(WEEK,@rec_w,DATEADD(MONTH,@rec_m,DATEADD(YEAR,@rec_y,@curevent))))
    if @nextevent>@end_date set @nextevent=null
    RETURN @nextevent
END

次に、Cursorループを作成して、作成時と更新時に別のテーブルのデータベースに保存されている要件に基づいてend_dateより短い場合は、すべてのイベント日を取得したり、要求に応じて表示および計算したりできます。

0
追加された