我的机器上运行SQL Server 2008与具有星期一作为一周的第一天区域设置。如果我在表中创建一个计算列计算一周的日期字段一天然后我得到2星期一的日期,而不是1。
有一些属性,我需要设置表或数据库或服务器?
一周的第一天是基于服务器的语言设置。对于美国英语的默认设置为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')
一个可怕的局面....假设你使用的是共享服务器和应用程序可以避开转向基于负载,由于某种原因,一台服务器是安装有不同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