sql >> データベース >  >> RDS >> Mysql

PHP / MySQL:データベース内の繰り返しイベントをモデル化しますが、日付範囲をクエリします

    idという1つの列だけで集計テーブルを作成します そのテーブルに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で集計テーブルを使用する代わりに、すべての日付を直接選択できます。キャッシュでき、再度計算する必要がないものはすべて優れています。



    1. OBJECT_NAME()を使用して、SQLServerのobject_idからオブジェクトの名前を取得します

    2. 多数のmysqlの更新と挿入を高速化

    3. Postgresqlでbigintフィールドを日付にフォーマットする方法は?

    4. Postgresの行サイズを理解する