加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

PHP / MySQL:模拟数据库中的重复事件,但查询日期范围

发布时间:2020-12-13 22:46:39 所属栏目:PHP教程 来源:网络整理
导读:我正在研究(我打算成为的)简单的 PHP / MySQL应用程序.作为其中的一部分,我希望能够为重复事件建模,但是我需要能够查询两个日期之间发生的所有事件(包括重复事件).事件只有一个日期,一天中的时间无关紧要. 我一直在研究这个问题,并研究过各种方法,包括Calend
我正在研究(我打算成为的)简单的 PHP / MySQL应用程序.作为其中的一部分,我希望能够为重复事件建模,但是我需要能够查询两个日期之间发生的所有事件(包括重复事件).事件只有一个日期,一天中的时间无关紧要.

我一直在研究这个问题,并研究过各种方法,包括Calendar Recurring/Repeating Events – Best Storage Method和Repeating calendar events and some final maths.

但是,我在网上找到的支持这种情况的数据库模式的任何示例似乎都支持查询某一天发生的事件.不支持在一系列日期之间发生的事件.

作为一个抽象的例子

事件表(带有某种重复表示):

Event   | Start Date   |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days

抽象查询的目标结果SELECT Events BETWEEN 09 / Dec / 2012和20 / Dec / 2012

Event   |  Date        |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Meeting | 17/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days
Lunch   | 11/Dec/2012  |   Every 1 days
Lunch   | 12/Dec/2012  |   Every 1 days
Lunch   | 13/Dec/2012  |   Every 1 days
etc...
Lunch   | 20/Dec/2012  |   Every 1 days

是否有支持这类查询的数据库架构?如何在两天之间发生的任何事件(包括重复事件)对该模式进行查询?

或者也许是用于重复事件的设计模式?

解决方法

我将使用一个名为id的col创建一个计数表,并用0到500的数字填充该表.现在我们可以轻松地使用它来进行选择而不是使用while循环.

Id
-------------------------------------
0
1
2
etc...

然后我将事件存储在一个表中,其中Name为varchar,startdate为datetime,重复为int

Name    | StartDate            |   Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00  |   7
Lunch   | 2012-12-10 00:00:00  |   1

现在我们可以使用计数表来选择两个日期之间的所有日期:

SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
ShowDate
-------------------------------------
2012-12-09 00:00:00
2012-12-10 00:00:00
2012-12-11 00:00:00
2012-12-12 00:00:00
2012-12-13 00:00:00
2012-12-14 00:00:00
2012-12-15 00:00:00
2012-12-16 00:00:00
2012-12-17 00:00:00
2012-12-18 00:00:00
2012-12-19 00:00:00
2012-12-20 00:00:00

然后我们在事件表上加入它来计算startdate和showdate之间的差异.我们通过重复列将结果分开,如果余数为0,我们匹配.

所有组合成为:

SELECT E.Id,E.Name,E.StartDate,E.Repeats,A.ShowDate,DATEDIFF(E.StartDate,A.ShowDate) AS diff
FROM events AS E,(
    SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
    FROM `tally`
    WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
    ORDER BY Id ASC
) a
WHERE MOD(DATEDIFF(E.StartDate,A.ShowDate),E.Repeats)=0
AND A.ShowDate>=E.StartDate

结果如何

Id  | Name       |StartDate             | Repeats   | ShowDate              | diff
---------------------------------------------------------------------------------
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-10 00:00:00   | 0
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-11 00:00:00   | -1
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-12 00:00:00   | -2
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-13 00:00:00   | -3
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-14 00:00:00   | -4
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-15 00:00:00   | -5
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-16 00:00:00   | -6
1   | Meeting    | 2012-12-10 00:00:00  | 7         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-17 00:00:00   | -7
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-18 00:00:00   | -8
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-19 00:00:00   | -9
2   | Lunch      | 2012-12-10 00:00:00  | 1         | 2012-12-20 00:00:00   | -10

现在你可以(并且应该!)加快速度.例如,通过直接在表中存储日期,您可以直接选择所有日期,而不是使用带有dateadd的计数表.你可以缓存并且不必再次计算的每件事都很好.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读