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语言设置中的依赖项。此函数使用英文硬编码名称,因此在其他语言中不起作用。请不要这样做。字符串比较不仅效率低下且不必要,而且假定它运行在英语服务器上;如果将脚本迁移到其他语言,如果服务器上的本机语言发生更改,或者即使连接上的语言不是英语,脚本也会失败。这是一个文化普遍性的定时炸弹——一个等待显现的潜在关键缺陷。