5

私は(私が意図していた)単純なPHP/MySQLアプリに取り組んでいます。その一環として、繰り返しイベントをモデル化できるようにしたいのですが、2つの日付の間に発生したすべてのイベント(繰り返しイベントを含む)を照会できる必要があります。イベントには日付のみがあり、時刻は関係ありません。

私はこれを研究しており、 カレンダーの繰り返し/繰り返しイベント-最良の保存方法繰り返しカレンダーイベントおよびいくつかの最終的な計算を含むさまざまなアプローチを調べてきました。

ただし、これをサポートするデータベーススキーマの例で、オンラインで見つけたものは、特定の日に発生したイベントのクエリのみをサポートしているようです。ある範囲の日付の間に発生したイベントはサポートされていません。

抽象例として

イベントテーブル(ある種の繰り返し表現付き):

Event   | Start Date   |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days

抽象クエリのターゲット結果SELECT Events BETWEEN 09/Dec/2012 AND 20/Dec/2012

Event   |  Date        |   Repeats
-------------------------------------
Meeting | 10/Dec/2012  |   Every 7 days
Meeting | 17/Dec/2012  |   Every 7 days
Lunch   | 10/Dec/2012  |   Every 1 days
Lunch   | 11/Dec/2012  |   Every 1 days
Lunch   | 12/Dec/2012  |   Every 1 days
Lunch   | 13/Dec/2012  |   Every 1 days
etc...
Lunch   | 20/Dec/2012  |   Every 1 days

この種のクエリをサポートするデータベーススキーマはありますか?2日間に発生したイベント(繰り返しイベントを含む)について、そのスキーマでクエリを実行するにはどうすればよいですか?

それとも、イベントを繰り返すために使用されるデザインパターンですか?

4

2 に答える 2

5

col を 1 つだけ呼び出して集計テーブルを作成し、idそのテーブルに 0 から 500 までの数字を入力します。これを使用して、while ループを使用する代わりに簡単に選択を行うことができます。

Id
-------------------------------------
0
1
2
etc...

次に、イベントをテーブルに保存しName as varcharstartdate as datetimerepeats 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 で集計テーブルを使用する代わりに、すべての日付を直接選択できます。キャッシュでき、再計算する必要がないものはすべて優れています。

于 2012-12-10T14:21:36.667 に答える
-3

私はあなたの目標をよく理解していませんでした.SQLでUNIQUE関数を探していたのでしょうか?

于 2012-12-10T14:08:06.247 に答える