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