在SELECT上为日历日期范围创建重复记录

时间:2010-05-29 02:26:28

标签: mysql select duplicates records

我已经构建了一个非常简洁的日历系统,但我需要做一个调整,以便我对它完全满意。

我的日历有三个表格:

calevents - 日历事件。

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

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

简短:

对于每个calevent,可以有许多caldates,每次出现calevent一个。所以每周重复一次并且跨越3天的故事可能会像这样产生问题:

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)的所有条件时,不仅返回上述两条记录,而且还返回date_start和date_end范围内每个日期的记录。 caldate。

所以,如果我搜索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

The Long:

我想这样做的原因是,当显示指定月份的事件列表(calevents)时,该事件的出现次数(caldates)将显示其跨越的每一天。

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

例如,如果在指定的月份内返回了以下条件:

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
"; 

非常感谢任何帮助或建议!

谢谢,

彼得

1 个答案:

答案 0 :(得分:2)

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

  • 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添加联接