ここで説明したとおりにします。無限のカレンダーが作成されます。
PHP/MySQL: データベースで繰り返しイベントをモデル化するが、日付範囲をクエリする
欠点は、クエリ中に計算が行われることです。高性能の Web サイトが必要な場合は、データのプリロードが最適です。1 つのイベントの値を簡単に変更できるようにするために、カレンダーのすべてのイベントを事前に読み込む必要さえありません。しかし、今から ... までのすべての日付を保存するのが賢明でしょう。
キャッシュされた値を使用すると、無限ではなくなりますが、速度は向上します。
簡単にアクセスできる awner のコピー:
col を 1 つだけ呼び出して集計テーブルを作成し、id
そのテーブルに 0 から 500 までの数字を入力します。これを使用して、while ループを使用する代わりに簡単に選択を行うことができます。
Id
-------------------------------------
0
1
2
etc...
次に、イベントをテーブルに保存しName as varchar
、startdate as datetime
repeats as int
Name | StartDate | Repeats
-------------------------------------
Meeting | 2012-12-10 00:00:00 | 7
Lunch | 2012-12-10 00:00:00 | 1
これで、集計テーブルを使用して、次を使用して 2 つの日付の間のすべての日付を選択できます。
SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
ShowDate
-------------------------------------
2012-12-09 00:00:00
2012-12-10 00:00:00
2012-12-11 00:00:00
2012-12-12 00:00:00
2012-12-13 00:00:00
2012-12-14 00:00:00
2012-12-15 00:00:00
2012-12-16 00:00:00
2012-12-17 00:00:00
2012-12-18 00:00:00
2012-12-19 00:00:00
2012-12-20 00:00:00
次に、これをイベント テーブルに結合して、開始日と表示日の差を計算します。この結果をrepeats
列で割り、余りが の場合、0
一致しています。
すべてを組み合わせると、次のようになります。
SELECT E.Id, E.Name, E.StartDate, E.Repeats, A.ShowDate, DATEDIFF(E.StartDate, A.ShowDate) AS diff
FROM events AS E, (
SELECT DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY) as showdate
FROM `tally`
WHERE (DATE_ADD('2012-12-09 00:00:00',INTERVAL Id DAY)<='2012-12-20 00:00:00')
ORDER BY Id ASC
) a
WHERE MOD(DATEDIFF(E.StartDate, A.ShowDate), E.Repeats)=0
AND A.ShowDate>=E.StartDate
その結果、
Id | Name |StartDate | Repeats | ShowDate | diff
---------------------------------------------------------------------------------
1 | Meeting | 2012-12-10 00:00:00 | 7 | 2012-12-10 00:00:00 | 0
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-10 00:00:00 | 0
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-11 00:00:00 | -1
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-12 00:00:00 | -2
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-13 00:00:00 | -3
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-14 00:00:00 | -4
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-15 00:00:00 | -5
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-16 00:00:00 | -6
1 | Meeting | 2012-12-10 00:00:00 | 7 | 2012-12-17 00:00:00 | -7
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-17 00:00:00 | -7
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-18 00:00:00 | -8
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-19 00:00:00 | -9
2 | Lunch | 2012-12-10 00:00:00 | 1 | 2012-12-20 00:00:00 | -10
これで、速度を上げることができます (そしてそうすべきです!)。たとえば、テーブルに日付を直接格納することで、dateadd で集計テーブルを使用する代わりに、すべての日付を直接選択できます。キャッシュでき、再計算する必要がないものはすべて優れています。