月曜日を週の最初の曜日とする地域設定のマシンでSQL Server 2008を実行しています。テーブルに計算列を作成して日付フィールドの曜日を計算すると、月曜日の日付は1ではなく2になります。
設定する必要があるテーブル、データベース、またはサーバーのプロパティはありますか?
週の最初の日は、サーバーの言語設定に基づいています。 us_englishのデフォルト設定は7(日曜日)です。
SELECT @@DATEFIRST
を使用すると、現在の週の最初の日を見つけることができます
ただし、これにはDATEFIRST
を使用できます。クエリの先頭に置くだけです
SET DATEFIRST 1;
これは、月曜日を現在の接続の週の最初の日に設定します。
クエリに設定するだけ
SET DATEFIRST 1;
値週の最初の日は1月曜日2火曜日3水曜日4木曜日5金曜日6土曜日7(デフォルト、米国英語)日曜日
DATEPART(dw, GETDATE())
を使用できますが、結果はSQLサーバーの設定_@@DATEFIRST
_の値に依存することに注意してください。これは週の最初の設定(ヨーロッパではデフォルト値7、つまり日曜日)です。
別の方法は、週の最初の曜日の値をパラメーターとして明示的に指定し、_@@DATEFIRST
_設定に依存しないようにすることです。次の式を使用して、必要なときにそれを実現できます。
_(DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1
_
ここで、_@WeekStartDay
_は、システムに必要な週の最初の日です(1から7まで、つまり月曜日から日曜日までを意味します)。
私はそれを以下の関数にラップして、簡単に再利用できるようにしました:
_CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
RETURNS INT
AS
BEGIN
--Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1
END
_
使用例:GetDayInWeek('2019-02-04 00:00:00', 1)
これは以下と同等です(ただし、DATEFIRST設定とは無関係です)。
_SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')
_
恐ろしい状況....共有サーバーを使用していて、アプリが負荷に基づいて別のサーバーに移動でき、何らかの理由で1つのサーバーが別のアプリケーションの別のfirstDateで設定されていたとします。そして、テーブル関数の曜日(つまり、この関数ではfirstdateを設定できません)。これは常に月曜日を最初の日として保証します。
CREATE FUNCTION fnGetMondayWD(@WD INT)
RETURNS INT
AS
BEGIN
/* think of 1 to 7 as a clock that can rotate forwards or backwards */
DECLARE @OFFSET INT, @calc INT;
SET @offset = @@DATEFIRST + @WD - 1;--Monday DateFirst
SET @calc = IIF(@offset > 7, @offset - 7, @offset); -- could be @offset % 7 (less readable more efficient)
RETURN @calc;
END;
go
-- Test Cases
SET datefirst 7
select dbo.fnGetMondayWD(2) Mon,
dbo.fnGetMondayWD(3)Tue,
dbo.fnGetMondayWD(4)Wed,
dbo.fnGetMondayWD(5)Thur,
dbo.fnGetMondayWD(6)Fri,
dbo.fnGetMondayWD(7)Sat,
dbo.fnGetMondayWD(1)Sun
SET datefirst 6
select dbo.fnGetMondayWD(3) Mon,
dbo.fnGetMondayWD(4)Tue,
dbo.fnGetMondayWD(5)Wed,
dbo.fnGetMondayWD(6)Thur,
dbo.fnGetMondayWD(7)Fri,
dbo.fnGetMondayWD(1)Sat,
dbo.fnGetMondayWD(2)Sun
SET datefirst 5
select dbo.fnGetMondayWD(4) Mon,
dbo.fnGetMondayWD(5)Tue,
dbo.fnGetMondayWD(6)Wed,
dbo.fnGetMondayWD(7)Thur,
dbo.fnGetMondayWD(1)Fri,
dbo.fnGetMondayWD(2)Sat,
dbo.fnGetMondayWD(3)Sun
SET datefirst 1
select dbo.fnGetMondayWD(1) Mon,
dbo.fnGetMondayWD(2)Tue,
dbo.fnGetMondayWD(3)Wed,
dbo.fnGetMondayWD(4)Thur,
dbo.fnGetMondayWD(5)Fri,
dbo.fnGetMondayWD(6)Sat,
dbo.fnGetMondayWD(7)Sun