2010-05-29 77 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