1

イベントを作成するカレンダー システムを開発しています。ユーザーが指定した月/年に (1 日に発生する) イベントを "ロール フォワード" できる必要があります。

たとえば、2013 年 3 月 4 日は月曜日です。曜日とその月内の位置に基づいて、指定された月/年によって、対応する日付が何であるかを判断できる必要があります。したがって、この例では、4 月に対応する日付は月曜日である 4 月 1 日になります。

別の例: 2013 年 3 月 13 日は水曜日なので、対応する 5 月の日付は 5 月 8 日になります。

ユーザーが指定した月/年が可変であるという事実がなければ、これはそれほど難しい作業ではありません。しかし、だから...

4

1 に答える 1

1

、 、、 、のDates5 つの列を含むテーブルがあり、将来の日付が入力されている場合は、次の操作を簡単に行うことができます。FullDateMonthDayYearDayOfWeek

@mおよび@yはロール フォワードするユーザー指定の月/年であり、@dはイベントの日付であると仮定します。

DECLARE @weekNumInMonth int =
(
    SELECT COUNT(1)
    FROM Dates
    WHERE Year = datepart(year @d) 
    AND Month = datepart(month, @d)
    AND DayOfWeek = datepart(weekday, @d)
    AND Day <= datepart(day, @d)
)

SELECT MAX(FullDate)
FROM 
(
    SELECT TOP @weekNumInMonth
    FROM Dates
    WHERE Year = @y
    AND Month = @m
    AND DayOfWeek = datepart(weekday, @d)
) x

日付テーブルがなければ、計算するだけです。

DECLARE @DOW int = datepart(weekday, @d)
DECLARE @firstDayInMonth date = dateadd(day, 1-datepart(day, @d), @d)
DECLARE @firstDayInMonthDOW int = datepart(weekday, @firstDayInMonth)
DECLARE @firstSameDayInMonth date = 
    dateadd(day, (7-(@firstDayInMonthDOW-@DOW))%7, @firstDayInMonth)
DECLARE @weekInMonth int = datediff(week, @firstSameDayInMonth, @d)

DECLARE @corr date = datefromparts(@y, @m, 1)
DECLARE @corrDOW int = datepart(weekday, @corr)
DECLARE @corrFirstSameDay date = dateadd(day, (7-(@corrDOW-@DOW))%7, @corr)

SELECT dateadd(week, @weekInMonth, @corrFirstSameDay)

SQL フィドルの例

少し醜いですが、それは次のとおりです。

  1. @dintoと同じ曜日の月の最初の日を取得し@firstSameDayInMonthます。
  2. @d0 ベースの整数として、対応する月内で# がどの週にあるかを把握し@weekInMonthます。@firstSameDayInMonthこれはとの間の週数です@d
  3. intoと同じ曜日の@m年、月の最初の日を取得します。@y@d@corrFirstSameDay
  4. に 0 ベースの週数を加算し@weekInMonth@corrFirstSameDay結果を取得します。

ワンライナーでできますか?もちろん、変数を置き換えるだけです。ただし、それは醜いので注意してください。読みやすさの欠如を除いて、そこから得られるものは何もありません。

SELECT dateadd(week, datediff(week, dateadd(day, (7-(datepart(weekday, dateadd(day, 
    1-datepart(day, @d), @d))-datepart(weekday, @d)))%7, dateadd(day, 
    1-datepart(day, @d), @d)), @d), dateadd(day, (7-(datepart(weekday,
    datefromparts(@y, @m, 1))-datepart(weekday, @d)))%7, datefromparts(@y, @m, 1)))
于 2013-03-01T04:03:55.920 に答える