หากต้องการตอบว่าทำไมคุณถึงได้รับวันจันทร์ไม่ใช่วันอาทิตย์:
คุณกำลังเพิ่มจำนวนสัปดาห์ในวันที่ 0 วันที่ 0 คืออะไร? 1900-01-01 วันที่ 1900-01-01 คืออะไร? วันจันทร์. ในรหัสของคุณคุณกำลังบอกว่าวันจันทร์ที่ 1 มกราคม 1900 ผ่านไปกี่สัปดาห์แล้ว เรียกสิ่งนั้นว่า [n] ตกลงตอนนี้เพิ่ม [n] สัปดาห์เป็นวันจันทร์ที่ 1 มกราคม 1900 คุณไม่ควรแปลกใจที่สิ่งนี้กลายเป็นวันจันทร์ 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
การตั้งค่าของคุณ(หรือรหัสของคุณกำลังทำงานสำหรับผู้ใช้ที่มีการตั้งค่าอื่น) โดยที่คุณยังคงต้องการวันอาทิตย์ไม่ว่าการตั้งค่าปัจจุบันจะเป็นอย่างไร หากคุณต้องการทั้งสองคำตอบหลอกแล้วคุณควรจะใช้ฟังก์ชั่นที่ไม่ขึ้นอยู่กับDATEFIRST
การตั้งค่าเช่น
SELECT DATEADD(DAY, 1-DATEPART(WEEKDAY, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
ดังนั้นหากคุณเปลี่ยนDATEFIRST
การตั้งค่าเป็นวันจันทร์วันอังคารคุณมีอะไรพฤติกรรมก็จะเปลี่ยนไป ขึ้นอยู่กับพฤติกรรมที่คุณต้องการคุณสามารถใช้หนึ่งในฟังก์ชันต่อไปนี้:
CREATE FUNCTION dbo.StartOfWeek1
(
@d DATE
)
RETURNS DATE
AS
BEGIN
RETURN (SELECT DATEADD(WEEK, DATEDIFF(WEEK, '19050101', @d), '19050101'));
END
GO
...หรือ...
CREATE FUNCTION dbo.StartOfWeek2
(
@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