定期的なイベントに関する質問が一般的であることは承知していますが、カレンダーアプリに関する質問以外に、定期的なイベントに関するこの特定の質問に対する回答を見つけることができませんでした。主な違いは、アプリ内のイベントです。多くの点で非常に似ていますが、カレンダーに関連する手荷物が少ないだけで、レポートまたはカレンダー形式ではなく単独でのみ表示されます。
カレンダーアプリと同じように。イベントは、1回限りの場合もあれば、毎週木曜日または毎月第1月曜日に、将来の事前設定された時間まで繰り返し発生する場合もあります。
イベントは、開始日と終了日、および「再通貨タイプID」を含むイベントテーブルに保存されます。「再通貨タイプ」が「なし」の場合、開始日と終了日は同じになります。イベントテーブルは、イベントタイプ名を保持する別のテーブルへのIDを保持します。例:「会議」または「週次レポート」
'再利用タイプ'例'再発なし'、'毎週月曜日'、'月の最初の月曜日'および'月の最後の土曜日'のリストを含む別の表があります。
検索を簡単にするために、別のテーブルには、1960年から2060年までの日付のリストと、月曜日かどうか、月曜日のどの月曜日であるかなど、各日付に関する関連情報が含まれています。
これにより、次のようなルックアップが可能になります。
SELECT DISTINCT(e.eventid),n.nameid,n.firstname,n.lastname,d.dt,r.recurring
FROM dates d
LEFT JOIN recurringtypes r
/* if event recurring every week E.g. 'Every Monday' */
ON (r.rectypeid BETWEEN 2 AND 8 AND r.day = d.dow)
/* if event recurring every month E.g. 'First Monday, every month' */
OR ((r.rectypeid BETWEEN 9 AND 36) AND r.day = d.dow AND r.occurrence = d.occurrence)
/* if event recurring every last week of month E.g. 'Last Monday, every month' */
OR (r.rectypeid >= 37 AND r.day = d.dow and r.islast = d.islast)
LEFT JOIN events e on e.rectypeid = r.rectypeid
LEFT JOIN eventtypes t ON e.eventtypeid = t.eventtypeid
LEFT JOIN names n ON e.namesid = n.namesid
WHERE (d.dt BETWEEN '2012/02/01' AND '2012/05/01')
ORDER BY d.dt;
これは、繰り返し発生するイベントを見つけるために必要なものであり、次のような出力を提供します。
+-----------+---------------+-------------------+-----------+------------+-------------------------------+
| eventid | nameid | lastname | firstname | dt | recurring |
+-----------+---------------+-------------------+-----------+------------+-------------------------------+
| 3291788 | 1728449 | smith | zoe | 2012-02-02 | First Thursday, every month |
| 3291797 | 1765432 | | | 2012-02-05 | First Sunday, every month |
| 3291798 | 1730147 | | | 2012-02-05 | First Sunday, every month |
| 3291803 | 1790061 | Carpenter | Richie | 2012-02-06 | Every Monday |
| 3291805 | 1790061 | Carpenter | Richie | 2012-02-08 | Second Wednesday, every month |
| 3291803 | 1790061 | Carpenter | Richie | 2012-02-13 | Every Monday |
| 3291799 | 1790061 | Carpenter | Richie | 2012-02-15 | Third Wednesday, every month |
| 3291803 | 1790061 | Carpenter | Richie | 2012-02-20 | Every Monday |
繰り返し発生するイベントを取得しないようにするには、より単純なクエリを使用できます。
SELECT n.nameid,n.lastname,n.firstname,e.firstdate,e.eventid,'No' as Recurring
FROM events e
LEFT JOIN names n ON n.names = e.namesid
AND e.rectypeid <= 1
AND e.firstdate BETWEEN '2012/02/01' AND '2012/05/01'
AND e.eventid IS NOT NULL ORDER BY e.firstdate;
これにより、最初のクエリと非常によく似た出力が得られますが、重要なのは、日付が日付テーブルではなくイベントテーブルからのものであるということです。
私の質問は、これらのクエリを組み合わせて、日付順に定期的および非定期的の両方のすべてのイベントを含む1つのリストを作成するにはどうすればよいですか?
これらはテーブルとそれらからの短縮された選択であり、簡潔にするために一部の列とすべてのインデックスが削除されています:)。同じ理由で、「names」テーブルは含まれていません。
CREATE TABLE events (
eventid int(11) NOT NULL AUTO_INCREMENT,
eventtypeid int(11) DEFAULT '0',
firstdate date DEFAULT '1960-01-01' COMMENT 'First event',
lastdate date DEFAULT '1960-01-01' COMMENT 'Last event',
rectypeid int(11) DEFAULT '1'
);
+---------+-------------+------------+------------+-----------+
| eventid | eventtypeid | firstdate | lastdate | rectypeid |
+---------+-------------+------------+------------+-----------+
| 3291803 | 16 | 2012-02-03 | 2012-04-11 | 3 |
| 3291797 | 8 | 2012-02-12 | 2012-02-22 | 9 |
| 3291798 | 5 | 2012-02-12 | 2012-02-12 | 9 |
| 3291788 | 8 | 2012-05-24 | 2015-01-16 | 13 |
| 3291805 | 10 | 2012-01-04 | 2012-02-14 | 19 |
| 3291799 | 16 | 2012-02-07 | 2012-10-24 | 26 |
| 3291804 | 5 | 2012-02-03 | 2012-08-22 | 41 |
+---------+-------------+------------+------------+-----------+
CREATE TABLE cmseventtypes (
eventtypeid int(11) NOT NULL AUTO_INCREMENT,
eventtype varchar(50) DEFAULT '' COMMENT 'Event type AKA name'
);
+-------------+----------------------+
| eventtypeid | eventype |
+-------------+----------------------+
| 1 | Follow up meeting |
| 2 | Reminder email due |
| 3 | Monthly meeting |
| 4 | Weekly report |
| 5 | Golf practice |
+------------------------------------+
CREATE TABLE recurringtypes (
rectypeid int(11) NOT NULL AUTO_INCREMENT,
recurring varchar(40) DEFAULT '',
day tinyint(4) DEFAULT '0',
occurrence tinyint(4) DEFAULT '0',
islast tinyint(4) DEFAULT '0'
);
+-----------+---------------------------+------+------------+--------+
| rectypeid | recurring | day | occurrence | islast |
+-----------+---------------------------+------+------------+--------+
| 1 | No | 0 | 0 | 0 |
| 2 | Every Sunday | 1 | 0 | 0 |
| 3 | Every Monday | 2 | 0 | 0 |
| 4 | Every Tuesday | 3 | 0 | 0 |
| 5 | Every Wednesday | 4 | 0 | 0 |
| 6 | Every Thursday | 5 | 0 | 0 |
| 7 | Every Friday | 6 | 0 | 0 |
| 8 | Every Saturday | 7 | 0 | 0 |
| 9 | First Sunday, every month | 1 | 1 | 0 |
| 10 | First Monday, every month | 2 | 1 | 0 |
+-----------+---------------------------+------+------------+--------+
CREATE TABLE dates (
dt date NOT NULL COMMENT 'Date',
daycount mediumint(9) NOT NULL DEFAULT '1',
year smallint(6) NOT NULL DEFAULT '1970',
month tinyint(4) NOT NULL DEFAULT '1',
dom tinyint(4) NOT NULL DEFAULT '1',
dow tinyint(4) NOT NULL DEFAULT '1',
occurrence tinyint(4) NOT NULL DEFAULT '0',
islast tinyint(1) NOT NULL DEFAULT '0'
);
+------------+----------+------+-------+-----+-----+------------+--------+
| dt | daycount | year | month | dom | dow | occurrence | islast |
+------------+----------+------+-------+-----+-----+------------+--------+
| 2012-02-02 | 734900 | 2012 | 2 | 2 | 5 | 1 | 0 |
| 2012-02-03 | 734901 | 2012 | 2 | 3 | 6 | 1 | 0 |
| 2012-02-04 | 734902 | 2012 | 2 | 4 | 7 | 1 | 0 |
| 2012-02-05 | 734903 | 2012 | 2 | 5 | 1 | 1 | 0 |
| 2012-02-06 | 734904 | 2012 | 2 | 6 | 2 | 1 | 0 |
| 2012-02-07 | 734905 | 2012 | 2 | 7 | 3 | 1 | 0 |
| 2012-02-08 | 734906 | 2012 | 2 | 8 | 4 | 2 | 0 |
| 2012-02-09 | 734907 | 2012 | 2 | 9 | 5 | 2 | 0 |
+------------+----------+------+-------+-----+-----+------------+--------+
上記のコードやテーブルレイアウトを使用することに完全に固執しているわけではありません。実用的なソリューションを歓迎します。私を次の方向に向けないでください。
カレンダーアプリケーションで定期的なイベントをモデル化するための最良の方法は何ですか?
カレンダーアプリを作成するときに、データベースに日付または繰り返しルールを保存する必要がありますか?
また
https://www.rfc-editor.org/rfc/rfc5545
私はそれらをチェックアウトしました、そしてそれらは非常に役に立ちましたが、私たちが意図したように同じことをしていませんでした。
TIA