2009-04-24 28 views
9

Tôi đang tìm một hàm đơn giản để lấy tuần của tháng (thay vì tuần dễ dàng trong năm) trong truy vấn mysql.Chức năng cho tuần trong tháng trong mysql

Điều tốt nhất tôi có thể đưa ra là:

WEEK(dateField) - WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField)-1 DAY)) + 1 

Tôi rất muốn biết nếu tôi reinventing the wheel ở đây, và nếu có một giải pháp dễ dàng hơn và sạch hơn?

Trả lời

12

AFAIK, không có tiêu chuẩn vào tuần đầu tiên của tháng.

Tuần đầu tiên của năm là tuần chứa Jan 4th.

Làm cách nào để bạn xác định tuần đầu tiên của tháng?

UPDATE:

Bạn sẽ cần phải viết lại truy vấn của bạn như thế này:

SELECT WEEK(dateField, 5) - 
     WEEK(DATE_SUB(dateField, INTERVAL DAYOFMONTH(dateField) - 1 DAY), 5) + 1 

để các hiệu ứng chuyển tiếp năm được xử lý một cách chính xác, và những tuần bắt đầu từ ngày Monday.

Nếu không, truy vấn của bạn vẫn ổn.

+0

Tôi đoán nó có thể không phải là giải pháp chung nhất, nhưng đối với những gì tôi cần một tuần bắt đầu vào thứ Hai. Vì vậy, nói rằng ngày 1 của tháng rơi vào ngày chủ nhật, chủ nhật đó sẽ được tính là tuần 1. Nếu điều đó có ý nghĩa ... – YiSh

8

Có một giải pháp thay thế đôi khi được sử dụng trong cơ sở dữ liệu báo cáo. Đó là để tạo ra một bảng, hãy gọi nó là ALMANAC, có một hàng mỗi ngày (khóa), và có mọi thuộc tính cần thiết của ngày có thể hữu ích cho mục đích báo cáo.

Ngoài tuần của cột tháng, có thể có cột cho biết ngày đó có phải là ngày lễ của công ty hay không và những thứ tương tự. Nếu công ty của bạn có năm tài chính bắt đầu vào tháng 7 hoặc tháng khác, bạn có thể bao gồm năm tài chính, tháng tài chính, tuần tài chính, v.v ... mà mỗi ngày thuộc về.

Sau đó, bạn viết một chương trình để điền bảng này ra khỏi không khí mỏng, được cung cấp một phạm vi ngày để điền. Bạn bao gồm tất cả các tính toán lịch điên chỉ một lần trong chương trình này.

Sau đó, khi bạn cần biết thuộc tính cho một ngày trong một số bảng khác, bạn chỉ cần tham gia và sử dụng cột. Vâng, đó là một lần nữa tham gia. Và không, bảng này không được chuẩn hóa. Nhưng nó vẫn là thiết kế tốt cho một số nhu cầu rất cụ thể.

0

Giải pháp của tôi trong một tuần bắt đầu vào Chủ nhật.

SELECT (1 + ((DATE_FORMAT(DATE_ADD(LAST_DAY(DATE_ADD('2014-07-17', 
    INTERVAL -1 MONTH)), INTERVAL 1 DAY),'%w')+1) + 
    (DATE_FORMAT('2014-07-17', '%d')-2)) DIV 7) "week_of_month"; 
1

(Chỉ cần làm rõ cho độc giả trong tương lai: câu trả lời này cho câu hỏi cũ này đã được bổ sung vì một bounty mà ngụ ý câu trả lời hiện nay là không đáp ứng, vì vậy tôi thêm này giải pháp/định nghĩa với thêm "tùy chọn cấu hình" cho tất cả các loại tình huống.)

Không có định nghĩa chuẩn cho Week of month, nhưng một giải pháp chung sẽ là công thức sau đây, bạn có thể tinh chỉnh yêu cầu của bạn:

select (dayofmonth(dateField) + 6 + (7 - "min_days_for_partial_week") 
     - (weekday(datefield) - "weekday_startofweek" + 7) MOD 7) DIV 7 as week_of_month; 

nơi

  • "weekday_startofweek" phải là được thay thế bằng ngày trong tuần mà bạn muốn là ngày đầu tiên trong tuần (0 = Monday, 6 = Sunday).
  • "min_days_for_partial_week" là số ngày mà tuần đầu tiên phải tính là tuần 1 (giá trị 1 đến 7). Giá trị chung sẽ là 1 (ngày đầu tiên của tháng luôn là tuần 1), 4 (điều này sẽ tương tự như "tuần iso trong năm", trong đó tuần đầu tiên của năm là tuần chứa thứ năm, vì vậy có ít nhất 4 ngày) và 7 (tuần 1 là tuần hoàn chỉnh đầu tiên).

Công thức này sẽ trả về giá trị 0 đến 6. 0 có nghĩa là tuần hiện tại là một tuần không có đủ ngày để tính là tuần 1 và 6 chỉ có thể xảy ra khi bạn cho phép một phần tuần có ít hơn 3 ngày là tuần 1.

Ví dụ:

Nếu ngày đầu tiên trong tuần là thứ Hai ("weekday_startofweek" = 0) và tuần 1 nên luôn có một tuần toàn bộ ("min_days_for_partial_week" = 7), điều này sẽ đơn giản hóa để

select (dayofmonth(dateField) + 6 - weekday(datefield)) DIV 7 as week_of_month; 

Ví dụ, đối với 2016-06-02 bạn sẽ nhận được 0, vì tháng sáu 2016 bắt đầu với một thứ tư y và cho 2016-06-06 bạn sẽ nhận được 1, vì đây là ngày Thứ Hai đầu tiên trong tháng Sáu năm 2016.

Để bắt chước công thức của bạn, nơi mà ngày đầu tiên của tuần luôn là tuần 1 ("min_days_for_partial_week" = 1), và tuần bắt đầu với Chủ nhật ("weekday_startofweek" = 6), đây sẽ là

select (dayofmonth(dateField) + 12 - (weekday(datefield) + 1) MOD 7) DIV 7 as week_of_month; 

Mặc dù bạn có thể muốn nhận xét đúng để biết trong 2 năm mà hằng số của bạn đến từ đó.

Các vấn đề liên quan