Вопрос по mysql – Повторение событий календаря и некоторые последние математические

12

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

Моя первая таблица «События».

<code>ID    NAME
1     Sample Event
2     Another Event
</code>

Моя вторая таблица 'events_meta', в которой хранятся повторяющиеся данные.

<code>ID    event_id      meta_key           meta_value
1     1             repeat_start       1336312800 /* May 7th 2012 */
2     1             repeat_interval_1  432000 /* 5 days */
</code>

С repeat_start является дата без времени в качестве метки времени unix, а repeat_interval - количество секунд в интервалах (432000 - 5 дней).

Затем у меня есть следующий MySQL, который я немного изменил по приведенной выше ссылке. Используемая ниже метка времени (1299132000, то есть 12 мая 2012 года) - это текущий день без времени.

<code>SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
RIGHT JOIN `events_meta` EM2 ON EM2.`meta_key` = CONCAT( 'repeat_interval_', EM1.`id` )
WHERE EM1.meta_key = 'repeat_start'
    AND (
        ( CASE ( 1336744800 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1336744800 - EM1.`meta_value` ) / EM2.`meta_value`
          END
        )
    ) = 1
</code>

В приведенном выше MySQL следующий код вычитает поле repeat_start (EM1.'meta_value') от текущей даты, а затем делит ее на поле повторяющегося интервала (EM2.'meta_value').

<code>ELSE ( 1336744800 - EM1.`meta_value` ) / EM2.`meta_value`
</code>

ИЛИ ЖЕ

<code>TODAYS DATE - START DATE / 5 DAYS
</code>

Итак, вот математика:

<code>1336744800 - 1336312800 = 432000
432000 / 432000 = 1
</code>

Теперь это работает отлично. Но если я поменяю текущую метку времени на 5 дней вперед на 1336312800, то есть 17-е число 2012 года, это будет выглядеть примерно так:

<code>1336312800 - 1336312800 = 864000
86400 / 432000 = 2
</code>

Что не работает, потому что оно равно 2, а в MySQL оно должно равняться 1. Поэтому я предполагаю, что мой вопрос заключается в том, как заставить MySQL распознавать целое число, а не делать это?

<code>...
WHERE EM1.meta_key = 'repeat_start'
    AND (
        ( CASE ( 1336744800 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1336744800 - EM1.`meta_value` ) / EM2.`meta_value`
          END
        )
    ) = IN (1,2,3,4,5,6,7,8,....)
</code>

Надеюсь, у меня есть смысл, и я надеюсь, что это просто математическая вещь или функция, которая есть в MySQL, которая поможет :) Спасибо за вашу помощь!

EDIT: THE ANSWER

Благодаря @eggypal ниже, я нашел свой ответ и, конечно, он был прост!

<code>SELECT EV.*
FROM elvanto_calendars_events AS EV
RIGHT JOIN elvanto_calendars_events_meta AS EM1 ON EM1.`event_id` = EV.`id`
RIGHT JOIN elvanto_calendars_events_meta AS EM2 ON EM2.`meta_key` = CONCAT( 'repeat_interval_', EM1.`id` )
WHERE EM1.meta_key = 'repeat_start'
AND ( ( 1336744800 - EM1.`meta_value` ) % EM2.`meta_value`) = 0
</code>
Математика даты, основанная на метках времени и фиксированном количестве секунд в дне, будет зависать от перехода на летнее время. DCoder
Я начал следить за этим и потерпел неудачуstackoverflow.com/questions/20286332/display-next-event-date Billa
Хороший звонок @DCoder. Я сохраняю все время как GMT, а затем использую функцию CONVERT_TZ, чтобы определитьrepeat_start Дата. Приведенные выше примеры кода не включают этот дополнительный код. Я думаю, что должно сделать трюк правильно? Ben Sinclair
Ваш запрос позволит мне увидеть результат для заданной даты начала и окончания?1336744800  выглядит как определенный день :( Murali Murugesan

Ваш Ответ

1   ответ
10

do, но суть вашего вопроса заставляет меня склоняться к предложению взглянуть на модульную арифметику: в SQL,a % b возвращаетremainder когдаa делится наb - если нет остатка (т.е.a % b = 0), затемa должен бытьexact multiple изb.

В твоем случае яthink Вы пытаетесь найти события, в которых время между началом события и некоторым заданным литералом точно кратно интервалу события:(literal - event_start) % event_interval = 0, Если оно ненулевое, значением является время до следующего вхождения послеliteral (и, следовательно, чтобы определить, произойдет ли это следующее вхождение в течение некоторого периода времени, скажем, дня, можно проверить, не является ли остаток такой постоянной величиной, например,(literal - event_start) % event_interval < 86400).

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

Извините, проигнорируйте мой последний комментарий, это сработало! Я отредактирую свой исходный пост с помощью окончательного кода, чтобы выручить других :) Ben Sinclair
Это хитрость! Мне удалось заставить его работать в PHP:echo ((strtotime('2012-05-22 00:00:00')- 1336312800) % 432000); Я пытался использовать% в MySQL, но это не сработало. Это эквивалент? Ben Sinclair
Я начал следить за этим и потерпел неудачу. Помоги мне.stackoverflow.com/questions/20286332/display-next-event-date

Похожие вопросы