2012-01-24 2 views
1

Я пытаюсь рассчитать прошлый год, начиная день «текущей недели NOW()» и конечный день этой недели. Наряду с этим мне нужно компенсировать, поскольку иногда стартовый день недели может быть не в воскресенье или в понедельник, а даже в четверг.Расчет последних лет Текущая неделя Начальная дата и конечная дата

Если неделя начинается во вторник, например, она закончится в понедельник. Учитывая это, если текущий день - четверг, я должен уметь вычислять вторник и понедельник.

Я понимаю, как получить последние годы текущего дня.

SELECT DATE_SUB(NOW(), INTERVAL 1 YEAR); 

Но с требованием компенсации здесь у меня возникли проблемы с расчетом начального дня той недели и дня окончания этой недели. Который должен быть в формате даты.

* Работа разъяснить это более ... Мой пример был выключен ...

*** Редактировать

Ради аргумента (и пример), скажем, что сегодня Ян 23, 2012. Моя задача - принять эту дату и вернуть даты начала и окончания на эту неделю предыдущего года.

Мои предположения:

1) a week is defined as having a thursday (ie 2011 week 1 is 1/2 - 1/8) 
2) start of week is Sunday 

Согласно схеме нумерации недели, как я понимаю это с вышеприведенными предположениями, неделя 1 является первой неделе с четверга. Это означает, что 23 января приходится на неделю 4 в 2012 году. Это подтверждается WEEK('2012-01-04') = 4. Таким образом, моя цель - выбрать начальную и конечную даты 4-й недели предыдущего года. В 2011 году результаты составят 23 января - 29 января.

Далее необходимо усложнить настройку начала недели (изменение предположения 2). Продолжайте использовать WK4 ... 2011, 23 января - 29 января, Sun - Sat, если я скажу, что начало недели - понедельник, то я бы корректировал даты на один ... давая 24 января - 30 января. на 2 ... 25 января - 31 января и т.д.

подход состоит из двух шагов: 1) вычислить начало и конец правда года неделя 2) вставьте его в «будущее» любым начальный день будет

Хотя скольжение в будущее может быть или не быть правильным, оно, по крайней мере, даст последовательные результаты, основанные на общепринятом понимании того, что означает «неделя 4».

К сожалению, PHP не обязательно является вариантом здесь. Нам нужно, чтобы это выполнялось внутри SELECT START_WEEK, END_WEEK;

Любой совет или помощь в решении этого вопроса будет очень полезен.

Благодаря

+0

Привет, действительно непонятно, что вы ищете здесь. Не могли бы вы объяснить, что вы подразумеваете под разными неделями, имеющими разные стартовые дни? Кроме того, приведу несколько примеров. Например, если сегодняшняя дата 2012-01-25, что должен вернуть запрос? –

+0

Я также недостаточно уверен, чтобы дать ответ, хотя из того, что я могу сказать, может быть лучше использовать PHP (или любой другой язык, который вы используете), чтобы рассчитать даты для запроса MySQL. – mrlee

ответ

1

Ну ISO 8601 предполагает:

  1. неделю определяется как имеющий Thu
  2. начало недели пн

Jan 23 падает в 4-й неделе 2012 года, которые вы можете подтвердите с помощью

SELECT WEEK('2012-01-23', 3) = 4; 

Неделя 4 из 2012 года - с 23 января по 29 января, которую вы можете подтвердить с календарем по адресу whatweekisit.com. В качестве запроса, можно вычислить с:

SELECT 
    WEEK('2012-01-23', 3) AS weekNumber, 
    DATE_SUB('2012-01-23', INTERVAL DAYOFWEEK('2012-01-23') - 2 DAY) AS startOfWeek, 
    DATE_ADD('2012-01-23', INTERVAL 8 - DAYOFWEEK('2012-01-23') DAY) as endOfWeek; 

Неделя 4 2011 является 24 января по 30 января (также confirmable по календарю). Это правда, что та же дата может не подпадать под текущий номер недели и прошлогоднюю неделю, но я не подозреваю, что они были бы совершенно разными.

SELECT 
    IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3), 
     DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY), 
     DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)) AS datetimeStart; 

Обратите внимание, что я всегда представляя расчеты дословно в нескольких местах (например, DATE_SUB('2012-01-23', INTERVAL 1 YEAR) 32 января 2011 г.); если вы делаете это в хранимой процедуре или UDF, вы, вероятно, можете использовать переменные, чтобы сделать его более кратким/удобочитаемым/поддерживаемым.

Теперь, когда началось и заканчивается неделя целевого года, вы можете просто применить свое смещение.Учитывая $weekDayStart является 0 - 6 (вс - сб):

SELECT 
    DATE_ADD(
     IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3), 
      DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY), 
      DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)), 
     INTERVAL $weekDayStart - 1 DAY) AS datetimeStart, 

    DATE_ADD(
     IF (WEEK('2012-01-23', 3) = WEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), 3), 
      DATE_SUB(DATE_SUB('2012-01-23', INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB('2012-01-23', INTERVAL 1 YEAR)) - 2 DAY), 
      DATE_SUB(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR), INTERVAL DAYOFWEEK(DATE_SUB(DATE_ADD('2012-01-23', INTERVAL 6 DAY), INTERVAL 1 YEAR)) - 2 DAY)), 
     INTERVAL $weekDayStart + 5 DAY) AS datetimeEnd; 

Так, работая через с входом 2012-01-23 и начать день Thurs уступит:

  1. 23 января 2012 = неделя 4
  2. неделя 4 2011 = 1/24-1/30
  3. смещение чт - пн (4 - 1) +3, который перемещает окно 27 января - 2 февраля 2011
0

Нашел ... Пришлось прочитать по этому вопросу немного больше. Это оказалось 7 разных запросов.

Мой Запрос базы:

Sunday Start Day of Week 
SELECT 
DATE_SUB(
DATE_ADD( 
STR_TO_DATE(CONCAT(YEAR('2012-01-04')-1, '-01-01'), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK), 
INTERVAL 6 DAY) START_DAY_OF_WEEK, 
DATE_ADD( 
STR_TO_DATE(CONCAT(YEAR('2012-01-04')-1, '-01-01'), '%Y-%m-%d'), 
INTERVAL WEEK('2012-01-04') WEEK) END_DAY_OF_WEEK; 

Это заставляет меня неделя 1 из 2011 Запуск этой недели 1/2 и заканчивая 1/8. Теперь, если моя неделя начинается на другой день, когда я добавить в смещение ...

Tuesday Start Day of Week 
SELECT 
DATE_SUB(
DATE_ADD( 
STR_TO_DATE(CONCAT(YEAR('2012-01-04')-1, '-01-01'), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK), 
INTERVAL 4 DAY) START_DAY_OF_WEEK, 
DATE_ADD(
DATE_ADD( 
STR_TO_DATE(CONCAT(YEAR('2012-01-04')-1, '-01-01'), '%Y-%m-%d'), #Get last year starting date. 
INTERVAL WEEK('2012-01-04') WEEK), 
INTERVAL 2 DAY) END_DAY_OF_WEEK; 

Это даст мне 1/4 начать день недели и заканчивается на 1/10.

Чтобы получить другие дни недели относительно просты:

  • воскресенья (первый запрос ...)
  • понедельника -5 начать день +1 дня завершения.
  • вторник -4 начало дня +2 конец день.
  • среда -3 начало дня +3 конец день.
  • четверг -2 начало дня -4 конец день.
  • Пятница -1 начало дня -5 конец день.
  • суббота -0 старт день -6 конец день.

Это 7 отдельных запросов, но дает мне возможность делать то, что я собираюсь делать.

Смежные вопросы