日曜日ではなく月曜日になる理由に答えるには:
日付0に週数を追加しています。日付0とは何ですか? 1900-01-01。 1900-01-01の日は何でしたか?月曜日。それで、あなたが言っているあなたのコードでは、1900年1月1日月曜日から何週間が経過しましたか?それを[n]と呼びましょう。では、1900年1月1日月曜日に[n]週間を追加します。これが月曜日になることは驚くべきことではありません。 DATEADD
週を追加したいということはわかりませんが、日曜日になるまでは、7日を追加し、さらに7日を追加します... DATEDIFF
のように 越えた境界のみを認識します。たとえば、切り上げまたは切り下げを行うための適切なロジックが組み込まれている必要があると不満を言う人もいますが、これらは両方とも1を返します。
SELECT DATEDIFF(YEAR, '2010-01-01', '2011-12-31');
SELECT DATEDIFF(YEAR, '2010-12-31', '2011-01-01');
日曜日を取得する方法に答えるには:
日曜日が必要な場合は、月曜日ではなく日曜日の基準日を選択してください。例:
DECLARE @dt DATE = '1905-01-01';
SELECT [start_of_week] = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP), @dt);
DATEFIRST
を変更しても、これは壊れません。 設定(または別の設定のユーザーに対してコードが実行されている)-現在の設定に関係なく、日曜日が必要な場合。これらの2つの答えがジャイブになりたい場合は、実行する関数を使用する必要があります。 DATEFIRST
に依存します 設定、例:
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
したがって、DATEFIRST
を変更した場合 月曜日、火曜日に設定すると、動作が変わります。必要な動作に応じて、次のいずれかの機能を使用できます。
CREATE FUNCTION dbo.StartOfWeek1 -- always a Sunday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
END
GO
...または...
CREATE FUNCTION dbo.StartOfWeek2 -- always the DATEFIRST weekday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, @d), @d));
END
GO
今、あなたはたくさんの選択肢を持っていますが、どれが最高のパフォーマンスを発揮しますか?大きな違いがあるとしたら驚きますが、これまでに提供されたすべての回答を収集し、2セットのテスト(1つは安価でもう1つは高価)を実行しました。ここでは、I / Oまたはメモリがパフォーマンスに関与していないため、クライアントの統計を測定しました(ただし、関数の使用方法によっては、これらが機能する場合があります)。私のテストでは、結果は次のとおりです。
「安い」割り当てクエリ:
Function - client processing time / wait time on server replies / total exec time
Gandarez - 330/2029/2359 - 0:23.6
me datefirst - 329/2123/2452 - 0:24.5
me Sunday - 357/2158/2515 - 0:25.2
trailmax - 364/2160/2524 - 0:25.2
Curt - 424/2202/2626 - 0:26.3
「高価な」割り当てクエリ:
Function - client processing time / wait time on server replies / total exec time
Curt - 1003/134158/135054 - 2:15
Gandarez - 957/142919/143876 - 2:24
me Sunday - 932/166817/165885 - 2:47
me datefirst - 939/171698/172637 - 2:53
trailmax - 958/173174/174132 - 2:54
必要に応じて、テストの詳細を中継できます。これはすでにかなり時間がかかっているため、ここで停止します。計算とインラインコードの数を考えると、Curtがハイエンドで最速として出てくるのを見て少し驚いた。たぶん、もっと徹底的なテストを実行して、それについてブログを書きます...皆さんが私にあなたの関数を他の場所に公開することに異議がなければ。