2010-05-29 62 views
1

我已经构建了一个漂亮的时髦日历系统,但有一个需要调整的地方,以便我完全满意。在SELECT上创建日历日期范围的重复记录

我的日历有三个表:

calevents - 该日历的事件。

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

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

短:

对于每个calevent,可以有很多caldates,一个用于calevent每次出现。这样每周重复和calevent跨越3天可能有这样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 

我想做的事情,选择是当所有caldates用于指定月份,如2010-06,返回不仅仅是什么上面有两条记录,但是每个日期的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 

的龙:

我想这样做的原因,是这样显示的事件列表(当calevents)在指定的月份中,该事件的发生次数(校准次数)将在其跨越的每一天显示。

我可以通过循环浏览当前月份的每一天,并显示每个caldate的副本,如果月份的日期介于date_start和date_end之间,可以通过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 
"; 

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

感谢,

彼得

回答

2

做你想做的是什么,最简单的事情:

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

  • 加入caldatesall_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如你所愿

+0

所以我应该创建日期的表永久正确的吗?......不是一个临时表之类的东西,对不对? 你会说什么是“合理的”? 10年的价值当然是3650记录。我不会认为那太糟糕了吧?随着我日历的工作方式,我可能会下降到一千以下,但我们假设3650是安全的。 感谢您的帮助! – peterallcdn 2010-05-29 02:53:34

+0

全是。永久表更有效率。 10年听起来很合理,但当然只有知道问题域的人才能对此做出最终裁决。但是,您可以始终让您的外部API查询最大的已知日期,并在需要时增加该表格 – DVK 2010-05-29 03:01:45

+0

好吧!我会走这条路。它可能比PHP循环更快,或者其他一些更复杂的mysql查询。感谢DVK。 – peterallcdn 2010-05-29 03:13:04