重复日历事件和一些最终的数学

Ben*_*air 13 mysql

我想尝试使用PHP/MySQL在日历上臭名昭着的重复事件.我终于找到了似乎有用的东西.我在这里找到了答案但是我有点难以完成它.

我的第一张桌子'事件'.

ID    NAME
1     Sample Event
2     Another Event
Run Code Online (Sandbox Code Playgroud)

我的第二个表'events_meta存储重复数据.

ID    event_id      meta_key           meta_value
1     1             repeat_start       1336312800 /* May 7th 2012 */
2     1             repeat_interval_1  432000 /* 5 days */
Run Code Online (Sandbox Code Playgroud)

假设repeat_start是没有时间作为unix时间戳的日期,repeat_interval是间隔之间的秒数(432000是5天).

然后我有以下MySQL,我从上面的链接稍微修改了一下.下面使用的时间戳(1299132000,即2012年5月12日)是当前没有时间的日期.

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
Run Code Online (Sandbox Code Playgroud)

在上面的MySQL中,以下代码EM1.'meta_value'从当前日期中扣除了repeat_start字段(),然后将其除以重复间隔字段(EM2.'meta_value').

ELSE ( 1336744800 - EM1.`meta_value` ) / EM2.`meta_value`
Run Code Online (Sandbox Code Playgroud)

要么

TODAYS DATE - START DATE / 5 DAYS
Run Code Online (Sandbox Code Playgroud)

所以这是数学:

1336744800 - 1336312800 = 432000
432000 / 432000 = 1
Run Code Online (Sandbox Code Playgroud)

现在这完美无缺.但是,如果我将当前时间戳提前5天更改为1336312800(即17th Mat 2012),它看起来有点像这样:

1336312800 - 1336312800 = 864000
86400 / 432000 = 2
Run Code Online (Sandbox Code Playgroud)

哪个不起作用,因为它等于2,而在MySQL中它需要等于1.所以我想我的问题是,如何让MySQL识别整数而不是必须这样做?

...
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,....)
Run Code Online (Sandbox Code Playgroud)

希望我有意义,我希望它只是一个简单的数学事物或MySQL有帮助的功能:)感谢您的帮助!

编辑:回答

感谢下面的@eggypal,我找到了答案,当然很简单!

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
Run Code Online (Sandbox Code Playgroud)

egg*_*yal 10

这不是完全清楚你想查询什么做的,但你的问题的JIST让我朝着建议你看看模运算瘦:在SQL,a % b返回余数时,a通过划分b-如果没有余数(即a % b = 0)然后a必须是整数倍b.

在您的情况下,我认为您正在尝试查找事件开始和某个给定文字之间的时间是事件间隔的精确倍数的事件:即 (literal - event_start) % event_interval = 0.如果它不为零,则该值是下一次出现之后的时间literal(因此,为了确定下一次出现是否在某个时间段内发生,例如一天,人们将测试剩余部分是否小于此类常数例如(literal - event_start) % event_interval < 86400).

如果这不是您所追求的,请详细说明您的查询要实现的目标.