0

毎日の値をタイムラインに保存する必要があります。つまり、データベースのすべてのユーザーには、次のように毎日のステータスが割り当てられている必要があります。

from 1.1.2000 to 28.05.2011 - status 1
from 29.05.2011 to 30.01.2012 - status 3
from 1.2.2012 to infinity - status 4

毎日1つのステータスのみを割り当てる必要があり、最後のステータスは終了しません(別のステータスが指定されるまで)。私の質問は、SQLデータベースでの効果的な表現は何ですか?明らかな解決策は、次のように、変更ごとに行を作成することです(最終日には、各範囲にステータスが割り当てられます)。

uptodate     status
28.05.2011   status 1
30.01.2012   status 3
01.01.9999   status 4

これには多くの問題があります。たとえば、2012年2月15日から別の範囲を追加したい場合は、最後の行も変更する必要があります。

uptodate     status
28.05.2011   status 1
30.01.2012   status 3
14.02.2012   status 4
01.01.9999   status 8

特に、リストの中央の範囲を変更したい場合は、重複やエラーがないことを確認するために多くのチェックが必要です-2012年1月29日から2012年2月10日までの新しいステータスの挿入は実装が困難です(ステータス3とステータス4のデータ範囲は、それに応じて縮小され、新しいステータス用のスペースが確保されます)。より良い解決策はありますか?


毎日のステータスを別々の行に保存するなど、完全に他の解決策を考えました。そのため、タイムラインに毎日の行があります。これにより、更新が簡単になります。開始から終了までの日付の行に新しいステータスを入力するだけです。もちろん、これは大量の不要なデータを生成するため、悪い解決策ですが、一貫性があり、管理が簡単です。間に何かあるのかと思っていたのですが、そうではないと思います。


より多くのコンテキスト:モデレーターが任意の日付にステータスを自由に割り当て、必要に応じて編集できるようにしたいと思います。ただし、ほとんどの場合、モデレーターは最後に新しいステータスデータ範囲を追加します。最後のステータスは本当に必要ありません。モデレーターが1か月の編集を終えたら、その月の各日のステータスに基づいてraportを生成する必要があります。ただし、モデレーターは数か月前にデータを編集したい場合があり(更新されたラポートに反映されます)、1つのステータスを1年前に設定できます。

4

2 に答える 2

0

テーブル構造には、ステータス期間の発効日と終了日を含める必要があります。これにより、ステータスが重複しないグループに効果的に「並べて表示」されます。最後の行には、(上記のように) ダミーの終了日または NULL が必要です。終了日にインデックスがある場合は、NULL の代わりに値を使用すると便利です。

この構造で、特定の日付のステータスを取得するには、次のクエリを使用します。

select *
from t
where <date> between effdate and enddate

期間の終了時に新しいステータスを追加するには、2 つの変更が必要です。

  1. 終了日が 01/01/9999 のテーブルの行を、終了日が昨日になるように変更します。
  2. 有効日が今日、終了日が 01/01/9999 の新しい行を挿入します。

これをストアド プロシージャでラップします。

過去のある日付のステータスを変更するには、履歴レコードの 1 つを 2 つに分割する必要があります。複数の日付では、複数のレコードを変更する必要がある場合があります。

日付範囲がある場合、特定の期間が重複するすべてのタイルをクエリで取得できます。

select *
from t
where <periodstart> <= enddate and <periodend> >= effdate
于 2012-05-28T23:07:05.530 に答える