SQL DATEPART(数据仓库,日期)需要星期一=1,星期天=7

SQL DATEPART(数据仓库,日期)需要星期一=1,星期天=7,sql,sql-server,Sql,Sql Server,我有一个查询,其中我获得了日期的工作日,但默认情况下: 星期日=1 Moday=2 等等 功能是: DATEPART(dw,ads.date) as weekday 我需要结果,以便: 星期日=7 星期一=1 等等 有什么捷径可走吗?或者我必须做一个案例陈述?您可以使用如下公式: (weekday + 5) % 7 + 1 如果您决定使用它,那么通过运行一些示例来说服自己,它实际上实现了您想要的功能是值得的 添加: 为了不受DATEFIRST变量的影响(可以设置为1到7之间的任何值)

我有一个查询,其中我获得了日期的工作日,但默认情况下:

  • 星期日=1

  • Moday=2

  • 等等

功能是:

DATEPART(dw,ads.date) as weekday
我需要结果,以便:

  • 星期日=7

  • 星期一=1

  • 等等


有什么捷径可走吗?或者我必须做一个
案例陈述

您可以使用如下公式:

(weekday + 5) % 7 + 1
如果您决定使用它,那么通过运行一些示例来说服自己,它实际上实现了您想要的功能是值得的

添加: 为了不受DATEFIRST变量的影响(可以设置为1到7之间的任何值),实际公式为:

(weekday  + @@DATEFIRST + 5) % 7 + 1
这就行了

SET DATEFIRST 1;

-- YOUR QUERY
例子

-- Sunday is first day of week
set datefirst 7; 
select DATEPART(dw,getdate()) as weekday


-- Monday is first day of week
set datefirst 1;
select DATEPART(dw,getdate()) as weekday

我建议您自己使用
datename()
编写case语句:


至少,如果有人在周开始的那一天更改参数,这一点不会改变。另一方面,它易受SQL Server所选语言的影响。

您可以告诉SQL Server使用星期一作为一周的开始,如下所示:

SET DATEFIRST 1
我想

DATEPART(dw,ads.date - 1) as weekday 

会有用的。

我认为这可能有用:

  select
    case when datepart(dw,[Date]) = 1 then 7 else DATEPART(DW,[Date])-1 end as WeekDay

另一个解决方案是:

ISNULL(NULLIF(DATEPART(dw,DateField)-1,0),7)

您需要先设置日期。看看这篇文章。我相信这会有所帮助


这是由运行SQL Server服务的帐户引起的。比如,

如果SQL Server服务在DOMAIN\MyUserAccount下运行,则需要登录并使用相关语言进行设置

如果未设置此帐户,则SQL Server将默认为sa帐户和在其下运行的语言

我发现我们的sa帐户设置为英语,星期一为DW=2。DOMAIN\MyUserAccount帐户已设置并更改为英国英语,星期一的DW将作为1返回

希望这有帮助

试试这个:

CREATE FUNCTION dbo.FnDAYSADDNOWK(
          @addDate AS DATE, 
          @numDays AS INT
       ) RETURNS DATETIME AS

    BEGIN
    WHILE @numDays > 0 BEGIN
        SET @addDate = DATEADD(day, 1, @addDate)    
        IF DATENAME(DW, @addDate) <> 'sunday' BEGIN
            SET @numDays = @numDays - 1 
        END
    END

    RETURN CAST(@addDate AS DATETIME)
END
创建函数dbo.fndaysadknowk(
@将日期添加为日期,
@整数日
)将日期时间返回为
开始
当@numDays>0开始时
设置@addDate=DATEADD(第1天,@addDate)
如果DATENAME(DW,@addDate)'sunday'开始
设置@numDays=@numDays-1
结束
结束
返回强制转换(@addDate作为DATETIME)
结束

看起来DATEFIRST设置是唯一的方法,但无法在标量/表值函数中生成SET语句。因此,跟随您的代码的同事很容易出错。(成为其他人的陷阱)

事实上,应该改进SQLServerDatePart函数,将其作为参数接受


同时,使用周的英文名称似乎是最安全的选择。

无论
DATEFIRST
设置如何,您都可以使用此公式:

((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - [first day that you need] ) % 7) + 1;
对于
monday=1

((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 1 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 7 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 5 ) % 7) + 1;
对于
sunday=1

((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 1 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 7 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 5 ) % 7) + 1;
对于
friday=1

((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 1 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 7 ) % 7) + 1;
((DatePart(WEEKDAY, getdate()) + @@DATEFIRST + 6 - 5 ) % 7) + 1;

我尝试了这个:(DATEPART(dw,ads.date)+5)mod 7+1作为工作日,但是我在mod上得到了一个错误。可能顺序不正确。啊,SQL Server使用不同的语法。我已经修复了我的答案,使用
%
而不是
mod
。虽然这对OP有效,但我认为如果用户的语言发生变化,它可能会崩溃。这个解决方案在几年前已经被提过好几次了。@RobForrest-老实说,我也不喜欢。一个假设特定的datefirst设置,另一个假设您可以设置它。但是,如果您在不同用户具有不同默认值的环境中创作视图或UDF,这两者都不可能。我在2018年6月使用了这个答案,现在我来到这里告诉大家@Damien_这个不信者是对的。他的评论是在几个月后添加的,我不认为在解决手头的问题时会出现这种情况。虽然这段代码可以回答这个问题;提供有关此代码为什么和/或如何回答此问题的其他上下文,可以提高其长期价值。非常有用的方法。您将一个非确定性函数替换为另一个非确定性函数。这没有任何意义,因为您只是将SET DATEFIRST的steting依赖项替换为SET语言设置中的依赖项。此函数使用英文硬编码名称,因此在其他语言中不起作用。请不要这样做。字符串比较不仅效率低下且不必要,而且假定它运行在英语服务器上;如果将脚本迁移到其他语言,如果服务器上的本机语言发生更改,或者即使连接上的语言不是英语,脚本也会失败。这是一个文化普遍性的定时炸弹——一个等待显现的潜在关键缺陷。