Tuần ISO và Tuần máy chủ SQL


33

Được rồi vì vậy tôi có một báo cáo thực hiện so sánh tuần này so với tuần trước và khách hàng của chúng tôi nhận thấy rằng dữ liệu của họ là "sôi nổi". Sau khi điều tra sâu hơn, chúng tôi thấy rằng nó đã không thực hiện đúng tuần theo tiêu chuẩn ISO. Tôi chạy kịch bản này như một trường hợp thử nghiệm.

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')

Khi chạy tôi đã nhận được những kết quả này.

Kết quả

Tôi nghĩ rằng điều này thật đặc biệt và vì vậy tôi đã đào thêm một chút và thấy rằng SQL Server tính ngày 1 tháng 1 là tuần đầu tiên của năm, nơi ISO tính ngày Chủ nhật đầu tiên của tháng 1 là tuần đầu tiên của năm.

Câu hỏi sau đó kết thúc là hai lần. Câu hỏi 1 tại sao lại như vậy? Câu hỏi 2 có cách nào để thay đổi điều này để tôi không phải sửa đổi tất cả mã của mình để sử dụng ISO_Weekở mọi nơi không?

Câu trả lời:


27

Quay lại khi SQL Server lần đầu tiên triển khai WEEKngày / phần, họ phải đưa ra lựa chọn. Tôi không nghĩ rằng thực sự có nhiều ý thức về nó, ngoại trừ việc tuân theo tiêu chuẩn phổ biến nhất vào thời điểm đó - hãy nhớ rằng đây là thời điểm mà việc tuân thủ các tiêu chuẩn không phải là ưu tiên hàng đầu (nếu không chúng ta không có những thứ như timestamp, IDENTITYTOP). Sau đó, họ đã thêm vào ISO_WEEK(2008 tôi tin) bởi vì cách giải quyết trong lúc đó là viết UDF vô hướng, chậm chạp, nhảm nhí của bạn - thực tế họ thậm chí đã tạo ra một tài liệu thực sự tồi tệ và đưa nó vào tài liệu chính thức (nó đã bị xóa như tôi có thể nói).

Tôi không biết cách để DATEPART(WEEKgiả vờ DATEPART(ISO_WEEK- Tôi nghĩ bạn sẽ phải thay đổi mã (và nếu bạn đang sử dụng kiểm soát nguồn, điều này sẽ không khó lắm - bạn đang thực hiện phép tính này bao nhiêu lần? Bạn đã nghĩ về việc tính toán nó ở đâu đó để mã của bạn không bị đánh đố với nó? Vì bạn đang thay đổi mã bây giờ, đây có thể là thời gian để xem xét điều này ...).

Và nếu bạn thực sự muốn câu trả lời tại sao? Tôi nghĩ bạn sẽ phải lấy một số nhà phát triển ban đầu để xác định lý do tại sao họ chọn mặc định mà họ đã làm. Một lần nữa, tôi nghĩ đó không phải là "F tiêu chuẩn!" sự lựa chọn, nhưng đúng hơn, "Tiêu chuẩn nào?"

Có một số thông tin ở đây có thể hữu ích:

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

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


Về mặt kỹ thuật, tất cả những gì tôi cần làm là thay đổi bảng DimCalWiki của mình, thật không may, các nhà phát triển của chúng tôi đã quyết định không sử dụng nó trong một số trường hợp báo cáo để nó được tính toán nhanh chóng. Nhìn chung, đây là một bài tập gây tò mò hơn bất kỳ cuộc khủng hoảng nào.
Zane

5
Tôi sẽ đề nghị các nhà phát triển của bạn cập nhật các báo cáo của họ để tuân theo các thực tiễn tốt nhất thay vì mã hóa cao bồi. Nhưng đó chỉ là tôi.
Aaron Bertrand

1
Tin tốt là trong vòng chưa đầy một tuần nữa họ sẽ không còn là nhà phát triển của tôi nữa. :)
Zane

2

Có một số cơ quan giả định các điều kiện khác nhau cho tuần đầu tiên của năm. Một số giả định ngày đầu tuần bắt đầu tuần đầu tiên nhưng ý tưởng phổ biến nhất là tuần đầu tiên có thứ Năm đầu tiên là tuần đầu tiên trong năm.

Vì vậy, ISO_WEEKchấp nhận điều đó và như thế nào trong năm 2010, 2011 hay 2012 như bạn có thể kiểm tra ISO_WEEKcho biết ngày 01 Tháng 1 là 52 hoặc 53 tuần trong khi WEEKhoặc WKhoặc WWnói họ là những tuần đầu tiên.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.