Функция на неделю месяца в MySQL - PullRequest
9 голосов
/ 24 апреля 2009

Я искал простую функцию, чтобы получить неделю месяца (а не простую неделю года) в запросе mysql.

Лучшее, что я мог придумать, было:

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

Я бы хотел знать, изобретаю ли я здесь колесо заново, и есть ли более простое и чистое решение?

Ответы [ 4 ]

15 голосов
/ 24 апреля 2009

AFAIK, в первую неделю месяца стандарта нет.

Первая неделя года - это неделя, содержащая Jan 4th.

Как вы определяете первую неделю месяца?

UPDATE:

Вам нужно будет переписать ваш запрос следующим образом:

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

так, чтобы переходы года обрабатывались правильно, а недели начинались с Monday.

В противном случае ваш запрос в порядке.

8 голосов
/ 24 апреля 2009

Существует альтернатива, которая иногда используется в отчетных базах данных. Это создание таблицы, назовем ее ALMANAC, которая имеет одну строку на дату (ключ) и имеет каждый необходимый атрибут даты, который может быть полезен для целей отчетности.

В дополнение к столбцу неделя месяца, может быть столбец для того, является ли дата выходным днем ​​компании и тому подобное. Если в вашей компании финансовый год начинается с июля или другого месяца, вы можете указать финансовый год, финансовый месяц, финансовую неделю и т. Д., К которым относится каждая дата.

Затем вы пишете одну программу, чтобы заполнить эту таблицу из воздуха, учитывая диапазон дат для заполнения. Вы включаете все сумасшедшие вычисления календаря только один раз в этой программе.

Затем, когда вам нужно узнать атрибут для даты в какой-то другой таблице, вы просто делаете объединение и используете столбец. Да, это еще одно присоединение. И нет, эта таблица не нормализована. Но это все еще хороший дизайн для определенных очень специфических потребностей.

1 голос
/ 02 июня 2016

(Просто чтобы уточнить для будущих читателей: этот ответ на этот старый вопрос был добавлен из-за щедрости, которая подразумевала, что текущий ответ не удовлетворяет, поэтому я добавил это решение / определение с дополнительными «параметрами конфигурации» для всех видов ситуации.)

Стандартного определения для Week of month не существует, но общим решением будет следующая формула, которую вы можете настроить в соответствии со своими потребностями:

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

где

  • "weekday_startofweek" должен быть заменен на день недели, которым вы хотите быть первым днем ​​недели (0 = Monday, 6 = Sunday).
  • "min_days_for_partial_week" - количество дней, которое первая неделя должна считать за неделю 1 (значения от 1 до 7). Общие значения будут 1 (первый день месяца всегда будет 1-й неделей), 4 (это будет похоже на «iso неделю года», где первая неделя года - это неделя, содержащая в четверг, так что минимум 4 дня) и 7 (неделя 1 - первая полная неделя).

Эта формула будет возвращать значения от 0 до 6. 0 означает, что текущая неделя является частичной неделей, в которой недостаточно дней, чтобы считаться неделей 1, и 6 может произойти, только если вы разрешаете частичным неделям с менее чем 3 днями быть неделей 1.

Примеры:

Если ваш первый день недели - понедельник ("weekday_startofweek" = 0), а неделя 1 всегда должна быть целой неделей ("min_days_for_partial_week" = 7), это упростится до

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

Например, для 2016-06-02 вы получите 0, потому что июнь 2016 года начался со среды, а для 2016-06-06 вы получите 1, поскольку это первый понедельник июня 2016 года.

Чтобы подражать вашей формуле, где первым днем ​​недели всегда является неделя 1 ("min_days_for_partial_week" = 1), а неделя начинается с воскресенья ("weekday_startofweek" = 6), это будет

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

Хотя вы, возможно, захотите это прокомментировать, чтобы через 2 года узнать, откуда пришли ваши константы.

0 голосов
/ 30 апреля 2014

Мое решение с неделю начинается в воскресенье.

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";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...