2013-05-14 132 views
3

我一直在四處尋找的代碼塊找到當前周的第一天,到處看的第一天,我看到這一點:SQL服務器 - 尋找周

DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0) 

每地方說這是我正在尋找的代碼。

這段代碼的問題是,如果你運行它的星期天,它會選擇下面的星期一。


如果我運行:

今天
SELECT GetDate() , DATEADD(WK, DATEDIFF(WK,0,GETDATE()),0) 

結果(星期二):

2013-05-14 09:36:39.650................2013-05-13 00:00:00.000 

這是正確的,它選擇週一13日。


如果我運行:

昨天
SELECT GetDate()-1 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-1),0) 

結果(星期一):

2013-05-13 09:38:57.950................2013-05-13 00:00:00.000 

這是正確的,它選擇週一13日。


如果我運行:

第12屆
SELECT GetDate()-2 , DATEADD(WK, DATEDIFF(WK,0,GETDATE()-2),0) 

結果(星期日):

2013-05-12 09:40:14.817................2013-05-13 00:00:00.000 

這是不正確的,它選擇週一13日的時候,應該選擇在上週一,六號。

任何人都可以照亮我這裏發生了什麼嗎?我發現很難相信沒有人指出這不起作用,所以我想知道我錯過了什麼。

+0

我改變[yourDate]由GETDATE()相信問題的根源在於使用了SQL Server解析爲'1900-01-01'的日期0--這是一個星期一。 – 2013-05-14 17:14:39

+1

[在SQL Server中獲取星期幾的第一天]可能的副本(http://stackoverflow.com/questions/7168874/get-first-day-of-week-in-sql-server) – Pondlife 2013-05-14 19:03:55

+1

@Pondlife:並非如此。問題是爲什麼不同的星期一會返回,這取決於日期是星期日還是星期幾。 – 2013-05-15 11:14:59

回答

4

嘗試這一個 -

SET DATEFIRST 1 

DECLARE @Date DATETIME 
SELECT @Date = GETDATE() 

SELECT CAST(DATEADD(DAY, 1 - DATEPART(WEEKDAY, @Date), @Date) AS DATE) 

SELECT CAST(@Date - 2 AS DATE), CAST(DATEADD(WK, DATEDIFF(WK, 0, @Date-2), 0) AS DATE) 

結果:

---------- ---------- 
2013-05-12 2013-05-13 
2

SQL Server有一個SET DATEFIRST功能,它允許你告訴它每週的第一天應該是什麼。 SET DATEFIRST = 1表示它將星期一視爲一週中的第一天。您應該通過@@ DATEFIRST檢查服務器的默認設置。或者你可以簡單地在查詢開始時改變它。

一些參考:

MSDN

Similar Question

+0

DATEDIFF(WEEK)無視DATEFIRST設置,這就是爲什麼在星期日日期(當@@ DATEFIRST = 1時)返回錯誤的星期一。 – 2013-05-15 11:11:07

4

這是DATEDIFF返回周的 「不正確」 的區別,這在週一錯了最終結果。這是因爲DATEDIFF(WEEK, ...)不尊重DATEFIRST設置,我假設您已設置爲1(星期一),並且始終認爲周過境從週六到週日,或者換句話說,無條件地認爲它是認爲星期日星期的第一天在這方面。

至於的解釋,到目前爲止,我還沒有能夠找到一個正式的一個,但我相信這一定有事情做與DATEDIFF功能是那些SQL Server將作爲always deterministic之一。顯然,如果DATEDIFF(WEEK, ...)依賴於DATEFIRST,它不能再被認爲是總是確定性的,我只能猜測並不是SQL Server的開發者想要它。

要找到星期日期的第一天,我就(和最常做的事實際上)使用的第一個建議在@Jasmina Shevchenko's answer

DATEADD(DAY, 1 - DATEPART(WEEKDAY, @Date), @Date) 

DATEPART不尊重DATEFIRST設置和(最有可能的結果)它從列表中缺失總是確定性的函數。

0

這就像一個魅力的工作對我來說:在不改變DATEFIRST變量

-- FirstDayWeek  
select dateadd(dd,(datepart(dw, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) * -1) + 2, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) as FirstDayWeek; 

-- LastDayWeek 
select dateadd(dd, (case datepart(dw, [yourDate]) when 1 then datepart(dw, dateadd(dd,-1,[yourDate])) else datepart(dw, [yourDate]) end * -1) + 8, case datepart(dw, [yourDate]) when 1 then dateadd(dd,-1,[yourDate]) else [yourDate] end) as LastDayWeek; 

設置星期日作爲一週的拳頭日:在不改變DATEFIRST變量

設置moday作爲一週的第一天

select convert(varchar(50), dateadd(dd, (datepart(dw, [yourDate]) * -1) + 2, [yourDate]), 103) as FirstDayWeek, convert(varchar(50), dateadd(dd, (datepart(dw, [yourDate]) * -1) + 8, [yourDate]), 103) as LastDayWeek; 

您可以測試