2011-08-16 22 views

Trả lời

17

Với bạn có yearcw (lịch tuần) như biến (ví dụ như từ một câu lệnh SELECT), bạn có thể nhận được DATE như sau:

DATE_SUB(
    DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK), 
    INTERVAL WEEKDAY(
    DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK) 
) -1 DAY), 

cụm từ DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK) là duplica ted; không muốn lưu trữ một biến. Câu lệnh SQL làm việc tốt cho tôi trên MySQL.

CẬP NHẬT: Chỉ cần làm rõ: WEEKDAY(DATE_ADD(MAKEDATE(year, 1), INTERVAL cw WEEK)) sẽ mang lại ngày đầu tiên trong tuần. Trừ một số từ nó (-1 cho Thứ Ba; -2 cho Thứ Tư và vv .. sẽ chọn một ngày cụ thể trong tuần cho bạn). Xem here.

+0

Điều gì làm lưu ý rằng có những tiêu chuẩn khác nhau 'sql?' số tuần! Hệ thống của Mỹ (tuần có Jan1 = tuần 1) có thể khác với hệ thống ISO (tuần thứ Năm đầu tiên của năm = tuần1). Vì vậy, hãy chắc chắn để kiểm tra này chống lại định nghĩa dự định của bạn trong một tuần. – Eljakim

+0

@Eljakim đó là chính xác và thực sự là một trong những lý do tại sao 'tuần của năm 'arithmetics là bằng cách nào đó kém hỗ trợ bởi MySQL. Tốt nhất là không sử dụng chúng. Trong thực tế di chuyển AWAY TỪ 'tuần của năm' là lý do tại sao tôi đã viết truy vấn đó một lần. – nre

+0

Không sử dụng 'MAKEDATE' cho điều này, nó sẽ tạo ra ngày sai, đặc biệt là khi bạn sử dụng ngày thương mại và số tuần dương lịch. Ví dụ: 'MAKEDATE (2017, 1)' sẽ cung cấp cho bạn 'Sun, 01 Jan 2017', * trong khi đây thực sự là tuần 52 của năm 2016 * và tuần đầu tiên của năm 2017 bắt đầu vào ngày 2 tháng 1. Thay vào đó, hãy sử dụng 'STR_TO_DATE ('2017 1 Thứ Hai' này, '% x% v% W')' để có được 'Thứ Hai' của tuần chính xác cho ra' Mon, 02 Jan 2017' –

0

Đây là một mẫu có thể giúp:

SET DATEFIRST 1 
declare @wk int set @wk = 33 
declare @yr int set @yr = 2011 

select dateadd (week, @wk, dateadd (year, @yr-1900, 0)) - 2 - 
    datepart(dw, dateadd (week, @wk, dateadd (year, @yr-1900, 0)) - 4) as date 

và kết quả là:

2011-08-16 00:00:00.000 

đó là ngày hôm nay (thứ ba).

0

Tôi nghĩ sẽ dễ dàng hơn khi viết logic của hàm bằng cách sử dụng php.

Nếu bạn sử dụng tập lệnh php, bạn có thể đặt tất cả các ngày theo định dạng tương tự như "ngày-tháng-năm" và sử dụng vòng lặp đi qua mỗi ngày (từ 1980 đến 2038 hoặc từ cột ngày mysql).

http://www.php.net/manual/en/function.date-format.php

Sau đó sử dụng định dạng ngày tháng vào những ngày trong vòng lặp đó để chuyển đổi chúng sang các ngày trong tuần.

Dưới đây là danh sách những thứ có thể được sử dụng trong các định dạng ngày tháng. http://www.php.net/manual/en/function.date.php D N l w tất cả đều giúp bạn với các ngày trong tuần.

9

Định nghĩa của tuần lịch tôi tìm thấy tất cả đã nói "một khoảng thời gian bảy ngày liên tục bắt đầu từ Chủ nhật".

Sau đây là MySQL cụ thể ... mileage của bạn có thể thay đổi ...

DATE_ADD (MAKEDATE (năm, 1), INTERVAL TUẦN cw) cho biết thêm những tuần từ ngày 1 năm mà không phải là chính xác. ..

mysql> select DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK); 
+----------------------------------------------+ 
| DATE_ADD(MAKEDATE(2011, 1), INTERVAL 1 WEEK) | 
+----------------------------------------------+ 
| 2011-01-08         | 
+----------------------------------------------+ 

Theo định nghĩa này, chỉ có ý nghĩa là có phạm vi tuần theo lịch từ 1-53 và có điều này là ngày chủ nhật của tuần đó. Như vậy, chúng tôi sẽ thêm 2 ngày vào ngày Chủ Nhật thứ n của năm để nhận được thứ ba.

Sau đây là ngày của chủ nhật đầu tiên của năm ...

mysql> select date_add('2012-01-01', interval (8 - dayofweek('2011-01-01')) % 7 DAY); 
+------------------------------------------------------------------------+ 
| date_add('2012-01-01', interval (8 - dayofweek('2011-01-01')) % 7 DAY) | 
+------------------------------------------------------------------------+ 
| 2012-01-02                | 
+------------------------------------------------------------------------+ 

vì vậy đây sẽ nhận được ngày chủ nhật thứ 10 (lưu ý khoảng 9 tuần kể từ khi chúng tôi đã ở 1) ...

mysql> select date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week); 
+-----------------------------------------------------------------------------------------------------+ 
| date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week) | 
+-----------------------------------------------------------------------------------------------------+ 
| 2010-03-07                       | 
+-----------------------------------------------------------------------------------------------------+ 

thêm 2 ngày để có được thứ ba ...

mysql> select date_add(date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week), interval 2 day); 
+--------------------------------------------------------------------------------------------------------------------------------+ 
| date_add(date_add(date_add('2010-01-01', interval (8 - dayofweek('2010-01-01')) % 7 DAY) , interval 9 week), interval 2 day) | 
+--------------------------------------------------------------------------------------------------------------------------------+ 
| 2010-03-09                              | 
+--------------------------------------------------------------------------------------------------------------------------------+ 

hoặc tổng quát hơn:

select 
date_add( 
    date_add( 
     date_add('<year>-01-01', interval (8 - dayofweek('<year>-01-01')) % 7 DAY) 
     , interval <week-1> week) 
    , interval <dayOfWeek> day 
); 
50

Trong MySQL, hàm STR_TO_DATE() có thể thực hiện thủ thuật chỉ trong một dòng! Ví dụ chúng ta muốn có được ngày thứ ba trong số 32 thứ tuần của năm 2013.

SELECT STR_TO_DATE('201332 Tuesday', '%X%V %W'); 

sẽ ra:

'2013-08-13' 

Tôi nghĩ rằng đây là giải pháp tốt nhất và ngắn nhất để vấn đề của bạn.

+2

Đây là @indago tuyệt vời - chính xác là những gì tôi đang được tìm kiếm. Và thanh lịch hơn nhiều so với các giải pháp khác. – Voodoo

+1

Rất thanh lịch! Khi xây dựng chuỗi YYYYCW cho 'STR_TO_DATE()' thì bạn có thể sử dụng '... STR_TO_DATE (CONCAT (YEAR (trường), LPAD (WEEKOFYEAR (trường, 2, '0')) ..' –

+0

@AlBundy bạn có thể sử dụng điều này để trích xuất từ ​​ngày hiện tại hoặc một trường cụ thể như bạn đã hiển thị ở trên, chỉ cần thay 'CURDATE()' bằng 'date_field' như thế này ' SELECT STR_TO_DATE (CONCAT (YEAR (CURDATE()), LPAD (WEEKOFYEAR) CURDATE()), 2, '0'), '', DAYNAME (CURDATE())), '% X% V% W'); ' – indago

0

Các giải pháp đã cho không xem xét, tuần đầu tiên của năm có thể bắt đầu vào cuối tháng 12. Vì vậy, chúng ta phải kiểm tra, nếu 1 tháng 1 thuộc về calendarweek năm cũ hay mới:

SET @week=1; 
SET @year=2014; 
SET @x_weeks_after_new_year=DATE_ADD(MAKEDATE(@year, 1), INTERVAL (SELECT IF(WEEKOFYEAR(MAKEDATE(@year, 1))>50 , 0 , -1))[email protected] WEEK); 
SELECT 
    CONCAT(@year, '-', @week) WeekOfYear, 
    @weekStart:=DATE_SUB(@x_weeks_after_new_year, INTERVAL WEEKDAY(@x_weeks_after_new_year) DAY) Monday, 
    DATE_ADD(@weekStart, INTERVAL 6 DAY) Sunday 

này sẽ cho kết quả:

+------------+------------+------------+ 
| WeekOfYear | Monday | Sunday | 
+------------+------------+------------+ 
| 2014-1 | 2013-12-30 | 2014-01-05 | 
+------------+------------+------------+ 
0

Trong quá trình tìm câu trả lời indago và sau đó thực hiện một loạt các bài kiểm tra, tôi đã nhận được tuần sau như là kết quả.

Tôi đã thực hiện một điều chỉnh nhỏ và các ngày sau đó khớp với nhau.

STR_TO_DATE ('# {year_week} thứ hai', '% x% v% W') - Đầu tuần

STR_TO_DATE ('# {year_week} Sunday', '% x% v% W') - cuối tuần

Bạn có thể so sánh kết quả ở đây http://www.epochconverter.com/date-and-time/weeknumbers-by-year.php?year=2015

-1

giải pháp upvoted làm việc cho tôi vào năm 2014 và 2015 nhưng không làm việc cho tôi vào năm 2016 (có thể vì sự khởi đầu của năm là ngày thứ hai và không phải ngày chủ nhật

Tôi đã sử dụng chức năng sau để sửa lỗi này:

STR_TO_DATE ( CONCAT (mod (day_nr + 1, 7), '/', week_nr, '/', năm), '% w /% u /% Y')

Trong dữ liệu của tôi: day_nr = 0 -> Thứ hai,

day_nr = 6 -> Chủ Nhật

Vì vậy, tôi đã phải khắc phục điều đó với một chức năng mod

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