要回答爲什麼你得到一個星期一,而不是星期日:
你加入了數週的日期0.什麼是日期0? 1900-01-01。 1900-01-01的那一天是什麼?星期一。所以在你的代碼中,你說的是,自1900年1月1日星期一以來已經過去了多少個星期?我們稱之爲[n]。好吧,現在在1900年1月1日星期一加上[n]個星期。你不應該感到驚訝,因爲這個星期一結束了。 DATEADD
不知道要添加星期,但只有在到達星期日之前,它只需添加7天,然後再添加7天,就像DATEDIFF
只能識別已經越過的邊界。例如,這些都返回1,儘管一些人抱怨,應該有內置了一些合理的邏輯舍向上或向下:
SELECT DATEDIFF(YEAR, '2010-01-01', '2011-12-31');
SELECT DATEDIFF(YEAR, '2010-12-31', '2011-01-01');
要回答如何得到一個星期日:
如果你想要一個星期天,然後選擇一個不是星期一而是星期天的基準日期。例如:
DECLARE @dt DATE = '1905-01-01';
SELECT [start_of_week] = DATEADD(WEEK, DATEDIFF(WEEK, @dt, CURRENT_TIMESTAMP), @dt);
,如果你(用不同的設置或你的代碼運行的用戶)更改DATEFIRST
設置這不會打破 - 只要你還願意星期天不管當前設置的。如果您希望將這兩個答案設置爲jive,那麼您應該使用確實取決於DATEFIRST
設置的的功能,例如,
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
所以,如果你改變你的DATEFIRST
設置星期一,星期二,你有什麼,該行爲可能會改變。根據你想要的是什麼行爲,你可以使用這些功能之一:
CREATE FUNCTION dbo.StartOfWeek1 -- always a Sunday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
END
GO
......或者......
CREATE FUNCTION dbo.StartOfWeek2 -- always the DATEFIRST weekday
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, @d), @d));
END
GO
現在,你有足夠的替代品,但它的效果最好?如果會有什麼重大分歧,我會感到驚訝,但我收集了迄今爲止提供的所有答案,並通過兩套測試 - 一種便宜,一種昂貴。我測量了客戶端統計數據,因爲我沒有看到I/O或內存在這裏的性能表現(雖然這些可能會根據功能的使用情況而發揮作用)。在我的測試結果是:
「便宜」轉讓查詢:
Function - client processing time/wait time on server replies/total exec time
Gandarez - 330/2029/2359 - 0:23.6
me datefirst - 329/2123/2452 - 0:24.5
me Sunday - 357/2158/2515 - 0:25.2
trailmax - 364/2160/2524 - 0:25.2
Curt - 424/2202/2626 - 0:26.3
「貴」任務查詢:
Function - client processing time/wait time on server replies/total exec time
Curt - 1003/134158/135054 - 2:15
Gandarez - 957/142919/143876 - 2:24
me Sunday - 932/166817/165885 - 2:47
me datefirst - 939/171698/172637 - 2:53
trailmax - 958/173174/174132 - 2:54
如果需要,我可以傳達我的測試細節 - 停在這裏因爲這已經變得相當冗長。考慮到計算和內聯代碼的數量,看到Curt以最快的速度出現在高端市場,我有點驚訝。也許我會運行一些更徹底的測試和博客關於它......如果你們不反對我在其他地方發佈你的功能。
'(@@ DATEFIRST + DATEPART(DW,@SomeDate))%7'保持不變,而不考慮@@ datefirst設置。星期一= 2. –