Как я могу получить дату N-го дня недели данного месяца в запросе MySQL?

Я искал ответы, и хотя я нашел ответы на похожие вопросы в Интернете, я не смог использовать их для своей цели. Мне нужна помощь.

Я создаю календарь, который поддерживает повторяющиеся события. Я почти закончил, но последняя часть самая сложная. Мне нужно иметь возможность поддерживать события, которые происходят в N-й X каждого Y месяцев, где X — заданный день недели, а Y — количество месяцев.

Я уже разобрался с частью «каждые Y месяцев» (которая находится от 2-й до последней строки в сегменте запроса ниже). Мне просто нужно получить "N-й будний день".

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

Вот часть запроса, чтобы вы могли понять, к чему я клоню:

WHEN event_recurring_pattern_type = 'monthly' AND event_recurring_monthly_type = 'dayxofeveryxmonths' THEN
    MOD(PERIOD_DIFF(CONCAT(event_date_year,event_date_month), CONCAT('$date_year','$date_month')), event_recurring_monthly_dayofeveryxmonths) = 0
    AND event_recurring_monthly_dayx = '$date_day'

WHEN event_recurring_pattern_type = 'monthly' AND event_recurring_monthly_type = 'thexweekdayofeveryxmonths' THEN
    MOD(PERIOD_DIFF(CONCAT(event_date_year,event_date_month), CONCAT('$date_year','$date_month')), event_recurring_monthly_dayofeveryxmonths) = 0
    AND '$date_timestamp' = {the date of the Nth weekday of $date_month}

Последняя строка должна сравнивать текущую дату вывода календаря (поскольку он строит календарь по одному дню за раз) с датой N-го дня недели любого месяца, в котором мы находимся в процессе вывода. Когда они совпадут, это событие будет выведено в календарь.

В этом случае $date_timestamp — это текущая дата вывода в формате «ГГГГ-ММ-ДД», поэтому N-й день недели, для которого я получаю дату, также должен быть в этом формате.

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

Заранее спасибо.

О да, и если это можно дополнительно создать, чтобы дополнительно получить ПОСЛЕДНИЙ указанный день недели данного месяца, это было бы еще лучше. PHP-скрипт сделал это, но, как я уже сказал, на этот раз я не могу сделать это с PHP.


person vertigoelectric    schedule 29.10.2012    source источник


Ответы (3)


Используйте DAYOFWEEK():

WHEN event_recurring_pattern_type = 'monthly'
 AND event_recurring_monthly_type = 'thexweekdayofeveryxmonths'
THEN MOD(
       PERIOD_DIFF(
         CONCAT(event_date_year,event_date_month),
         CONCAT('$date_year','$date_month')
       ), event_recurring_monthly_dayofeveryxmonths
     ) = 0
 AND DAYOFWEEK('$date_timestamp') = event_recurring_monthly_dayofweek

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

person Justin ᚅᚔᚈᚄᚒᚔ    schedule 29.10.2012
comment
Спасибо, но я не думаю, что это делает то, что я прошу. Похоже, что ваша оценка после И действительно поместит его в определенный день недели, но он будет помещать его в этот день для каждой недели в месяце. Я только хочу, чтобы он соответствовал N-му дню недели. Например, только третья пятница месяца, или второй вторник и т.д. - person vertigoelectric; 30.10.2012

Самый простой способ — написать программу для заполнения новой таблицы нужной вам информацией. Для далекого будущего не потребуется очень большая таблица. Затем просто присоединитесь к таблице в своем запросе.

person Mark Ransom    schedule 29.10.2012
comment
Я действительно не знаю, как это поможет или как я бы даже реализовал это. Можете ли вы привести пример? - person vertigoelectric; 29.10.2012

Я собираюсь попробовать это (еще не было проверено в полевых условиях):

 SET @target = DATE('2013-06-15');
SELECT  1 + ( 
 IF( MONTH(DATE_SUB( @target, INTERVAL  7 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 14 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 21 DAY)) = MONTH(@target), 1, 0) +
 IF( MONTH(DATE_SUB( @target, INTERVAL 28 DAY)) = MONTH(@target), 1, 0) ) AS nth_weekday_of_month;

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

person R. Flowers    schedule 21.02.2013