【问题标题】:Create Duplicate Records on SELECT for Calendar Date Range在 SELECT 上为日历日期范围创建重复记录
【发布时间】:2011-02-25 09:15:24
【问题描述】:

我已经建立了一个非常漂亮的日历系统,但我需要进行一些调整,以便我对它完全满意。

我的日历有三个表格:

calevents - 日历事件。

caldates - 每个事件的发生次数和每次发生的日期范围。

calcats - 可应用于事件的类别。

短篇:

对于每个 calevent,可以有多个 caldate,每个 calevent 出现一个。因此,每周重复并跨越 3 天的 calevent 可能具有这样的 caldates:

date_id   date_eid   date_start   date_end
2         37         2010-06-21   2010-06-23
3         37         2010-06-28   2010-06-30
7         37         2010-07-05   2010-07-07
9         37         2010-07-12   2010-07-14

我想要做的是,在选择指定月份(例如 2010-06)的所有 caldates 时,不仅返回上面的两条记录,而且返回每个日期在 date_start 和 date_end 范围内的记录日期。

所以如果我搜索 2010-06,我会得到:

date_id   date_eid   date_start   date_end     date_day
2         37         2010-06-21   2010-06-23   2010-06-21
2         37         2010-06-21   2010-06-23   2010-06-22
2         37         2010-06-21   2010-06-23   2010-06-23
3         37         2010-06-28   2010-06-30   2010-06-28
3         37         2010-06-28   2010-06-30   2010-06-29
3         37         2010-06-28   2010-06-30   2010-06-30

长篇:

我想这样做的原因是,当显示指定月份的事件(日历)列表时,将在其跨越的每一天显示该事件的发生(日历)。

我可以通过循环遍历当前月份的每一天并在月份日期介于 date_start 和 date_end 之间时显示每个 caldate 的副本来使用 php 执行此操作。但是这样做会阻止我在需要时使用记录分页。

例如,如果在指定月份返回以下caldates:

date_id   date_eid   date_start   date_end
2         37         2010-06-21   2010-06-27
94        53         2010-06-09   2010-07-08

进行记录分页会看到这只有 2 条记录(“行”)。但是用 PHP 循环遍历它们会生成 29 个“行”。

所以,我想如果我使用 mysql 而不是 PHP 来创建每一行,我可以实现同样的事情,并且如果一个月有很多事件/日期,我仍然可以使用分页。

就性能而言,我不确定哪个选项更有效。两者都会向浏览器发送相同数量的信息,因此真正重要的是生成信息所需的工作。

我当前的查询获取指定月份的所有事件,并让事情变得更复杂......将它们与其事件和类别连接起来,如下所示:

$sql_to_execute = "
SELECT
  date_id,
  date_eid,
  date_start,
  date_end,
  event_id,
  event_title,
  event_category,
  event_private,
  event_location,
  SUBSTRING_INDEX(event_detailsstripped, ' ', 40) AS event_detailsstripped,
  event_time,
  event_starttime,
  event_endtime,
  event_active,
  cat_colour
FROM
  (
  caldates
LEFT JOIN
  calevents
ON
  caldates.date_eid = calevents.event_id
  )
LEFT JOIN
  calcats
ON
  calevents.event_category = calcats.cat_id
WHERE
  date_start <= '".mysql_real_escape_string($dbi_list_end_date)."'
  AND date_end >= '".mysql_real_escape_string($dbi_list_start_date)."'
  ".$dbi_category."
ORDER BY
  date_start ASC
"; 

任何帮助或建议将不胜感激!

谢谢,

彼得

【问题讨论】:

    标签: mysql select duplicates records


    【解决方案1】:

    做你想做的最简单的事情是:

    • Generate a table of ALL dates (within a reasonable range)

    • caldates 表加入all_dates 表:

      SELECT * FROM caldates, all_dates
      WHERE all_dates.date BETWEEN "2010-06-01" AND "2010-06-30"
      AND   all_dates.date BETWEEN caldates.date_start AND caldates.date_end
      

      根据需要添加到 calevents 的连接

    【讨论】:

    • 所以我应该创建永久正确的日期表?...不是临时表或类似的东西,对吧?你会说什么是“合理的”? 10 年的价值当然是 3650 条记录。我不会觉得那太糟糕了吧?以我的日历工作方式,我可能会下降到一千以下,但为了安全起见,我们假设 3650。感谢您迄今为止的帮助!
    • 是的。永久表更有效。 10 年听起来很合理,但当然只有了解问题领域的人(您)才能对此做出最终裁决。但是您始终可以让您的外部 API 查询最大的已知日期,并在需要时增加该表
    • 好的,太好了!我会走这条路。它也可能比 php 循环或其他更复杂的 mysql 查询更快。谢谢 DVK。
    猜你喜欢
    • 2013-03-23
    • 1970-01-01
    • 2012-06-02
    • 2021-09-08
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 2017-12-02
    相关资源
    最近更新 更多