ISO Week กับ SQL Server Week


33

โอเคฉันมีรายงานที่ทำเปรียบเทียบสัปดาห์นี้กับสัปดาห์ที่แล้วและลูกค้าของเราสังเกตเห็นว่าข้อมูลของพวกเขานั้น "ขี้ขลาด" จากการตรวจสอบเพิ่มเติมเราพบว่ามันไม่ได้ทำอย่างถูกต้องเป็นสัปดาห์ตามมาตรฐาน ISO ฉันรันสคริปต์นี้เป็นกรณีทดสอบ

SET DATEFIRST 1
SELECT DATEPART(WEEK, '3/26/13')
    , DATEPART(WEEK, '3/27/12')
    , DATEPART(WEEK, '3/20/12')
    , DATEPART(WEEK, '1/2/12')
SELECT DATEPART(ISO_WEEK, '3/26/13')
    , DATEPART(ISO_WEEK, '3/27/12')
    , DATEPART(ISO_WEEK, '3/20/12')
    , DATEPART(ISO_WEEK, '1/2/12')

เมื่อรันฉันจะได้ผลลัพธ์เหล่านี้

ResultSet

ฉันคิดว่านี่เป็นเรื่องแปลกและดังนั้นฉันจึงขุดเพิ่มเติมและพบว่า SQL Server นับ 1 มกราคมเป็นสัปดาห์แรกของปีที่ ISO นับวันอาทิตย์แรกของเดือนมกราคมเป็นสัปดาห์แรกของปี

คำถามนั้นจบลงด้วยการเป็นสองเท่า คำถามที่ 1 ทำไมนี่คืออะไร คำถามที่ 2 มีวิธีใดบ้างที่จะเปลี่ยนแปลงสิ่งนี้ดังนั้นฉันไม่ต้องแก้ไขโค้ดทั้งหมดเพื่อใช้ในISO_Weekทุกที่ใช่ไหม

คำตอบ:


27

ย้อนกลับไปเมื่อ SQL Server ใช้งานWEEKวันที่ / ส่วนแรกพวกเขาต้องทำการเลือก ฉันไม่คิดว่าจะมีสติมากเกี่ยวกับเรื่องนี้ยกเว้นเพื่อให้สอดคล้องกับมาตรฐานที่พบบ่อยที่สุดในเวลานั้น - โปรดจำไว้ว่านี่เป็นช่วงเวลาที่การปฏิบัติตามมาตรฐานไม่ใช่ลำดับความสำคัญสูงสุด (ไม่เช่นนั้นเราจะไม่มีสิ่งต่าง ๆ เช่นtimestamp, IDENTITYและTOP) พวกเขาเพิ่มในภายหลังISO_WEEK(2008 ฉันเชื่อ) เนื่องจากวิธีแก้ปัญหาในระหว่างนี้คือการเขียน UDF scalar ของคุณช้าเส็งเคร็ง - ในความเป็นจริงพวกเขายังสร้างเลวร้ายจริงๆและวางไว้ในเอกสารอย่างเป็นทางการ อย่างที่ฉันบอกได้)

ฉันไม่รู้วิธีที่จะDATEPART(WEEKเสแสร้งว่าเป็นDATEPART(ISO_WEEK- ฉันคิดว่าคุณจะต้องเปลี่ยนรหัส (และถ้าคุณใช้การควบคุมแหล่งที่มาสิ่งนี้ไม่ควรยากมาก - คุณมีการคำนวณนี้กี่แห่ง? คุณคิดว่าจะคำนวณมันไว้ที่ใดที่หนึ่งเพื่อไม่ให้โค้ดของคุณยุ่งกับมันเนื่องจากคุณเปลี่ยนรหัสตอนนี้อาจเป็นเวลาที่จะพิจารณาเรื่องนี้ ... )

และถ้าคุณต้องการคำตอบจริงๆทำไม? ฉันคิดว่าคุณจะต้องคว้านักพัฒนาดั้งเดิมบางคนเพื่อพิจารณาว่าทำไมพวกเขาถึงเลือกค่าเริ่มต้นที่พวกเขาทำ อีกครั้งฉันคิดว่ามันไม่ใช่ "F มาตรฐาน!" ทางเลือก แต่เป็น "มาตรฐานอะไร"

มีข้อมูลบางอย่างที่นี่ที่อาจเป็นประโยชน์:

https://stackoverflow.com/questions/348880/getting-week-number-off-a-date-in-ms-sql-server-2005

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/iso-week-in-sql-server


ในทางเทคนิคทั้งหมดที่ฉันต้องทำคือเปลี่ยนตาราง DimCalendar ของฉันโชคไม่ดีที่นักพัฒนาของเราตัดสินใจที่จะไม่ใช้มันในหลาย ๆ อินสแตนซ์ของรายงานดังนั้นมันจึงถูกคำนวณทันที โดยส่วนใหญ่นี่เป็นการออกกำลังกายด้วยความอยากรู้อยากเห็นมากกว่าวิกฤตประเภทใด
Zane

5
ฉันขอแนะนำให้คุณให้นักพัฒนาของคุณอัปเดตรายงานของพวกเขาเพื่อปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดแทนที่จะใช้รหัสโคบาล แต่นั่นเป็นเพียงฉัน
Aaron Bertrand

1
ข่าวดีก็คือในเวลาน้อยกว่าหนึ่งสัปดาห์พวกเขาจะไม่ใช่นักพัฒนาของฉันอีกต่อไป :)
Zane

2

มีหลายหน่วยงานที่สมมติว่ามีเงื่อนไขต่างกันสำหรับสัปดาห์แรกของปี บางคนคิดว่าวันแรกของสัปดาห์เริ่มต้นสัปดาห์แรก แต่ความคิดที่พบบ่อยที่สุดคือสัปดาห์แรกที่มีวันพฤหัสบดีแรกคือสัปดาห์แรกของปี

ดังนั้นISO_WEEKยอมรับและชอบในปี 2010, 2011 หรือ 2012 ในขณะที่คุณสามารถตรวจสอบISO_WEEKว่า 1 มกราคมเป็น 52 หรือ 53 สัปดาห์ในขณะที่WEEKหรือWKหรือWWบอกว่าพวกเขาเป็นสัปดาห์แรก

SELECT DATEPART (WW,'01/01/2010')   --> 1
SELECT DATEPART (WK,'01/01/2010')   --> 1
SELECT DATEPART (WEEK,'01/01/2010')   --> 1
SELECT DATEPART (ISO_WEEK,'01/01/2010')   --> 53
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.