SQL Server - 查找一周的第一天

Ron*_*ser 4 t-sql sql-server sql-server-2012

我一直在寻找一大堆代码来找到本周的第一天,我看到的每个地方都看到了这个:

DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0)
Run Code Online (Sandbox Code Playgroud)

每个地方都说这是我正在寻找的代码.

这段代码的问题在于,如果你在星期天运行它,它会选择下一个星期一.


如果我跑:

SELECT GetDate() , DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0)
Run Code Online (Sandbox Code Playgroud)

今日(星期二)的结果:

2013-05-14 09:36:39.650................2013-05-13 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

这是正确的,它选择了13日星期一.


如果我跑:

SELECT GetDate()-1 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-1),0)
Run Code Online (Sandbox Code Playgroud)

昨天(星期一)的结果:

2013-05-13 09:38:57.950................2013-05-13 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

这是正确的,它选择了13日星期一.


如果我跑:

SELECT GetDate()-2 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-2),0)
Run Code Online (Sandbox Code Playgroud)

12日(星期日)的结果:

2013-05-12 09:40:14.817................2013-05-13 00:00:00.000
Run Code Online (Sandbox Code Playgroud)

这是不正确的,它选择在13日星期一选择上一个星期一,即6日.

谁能照亮我这里发生了什么?我发现很难相信没有人指出这不起作用,所以我想知道我错过了什么.

And*_*y M 6

这是DATEDIFF返回周的"不正确"差异,最终导致错误的星期一.这是因为DATEDIFF(WEEK, ...)不尊重DATEFIRST设置,我假设你设置为1(星期一),而是总是认为周过来是从星期六到星期日,换句话说,它无条件地认为星期日到在这种情况下,成为一周第一天.

至于对此的解释,到目前为止我还没有找到一个正式的,但我相信这必须与DATEDIFF作为SQL Server对待之一的函数一样具有确定性.显然,如果DATEDIFF(WEEK, ...)依赖于它DATEFIRST,它就不再被认为总是确定性的,我只能猜测不是SQL Server的开发人员想要它.

为了找到一周中第一天的日期,我会(并且大多数情况下实际上)使用@Jasmina Shevchenko的答案中的第一个建议:

DATEADD(DAY, 1 - DATEPART(WEEKDAY, @Date), @Date)
Run Code Online (Sandbox Code Playgroud)

DATEPART确实尊重DATEFIRST设置和(最有可能的结果)它总是在确定性函数列表中不存在.