0

関連するさまざまなテーブルを含む一連の SQLite データベースにいくつかのデータがあります。各テーブルには、各レコードが有効な日付範囲を表す開始日列と終了日列があります。SQLite データベースには、主に C# と System.Data.SQLite ライブラリを使用してアクセスします。

日付範囲が重複する、または重複しない結合などのクエリを実行できるようにしたいと考えています。オーバーラップするデータを簡単に結合できることがわかりました。

SELECT a.field, max(a.start, b.start) as start, min(a.end, b.end) as end
FROM a
INNER JOIN b
ON a.field = b.field AND NOT(a.start > b.end OR b.start > a.end);

しかし、一致するbがないaの期間を取得する方法がわかりません。オーバーラップがない場所でレコードを取得するのは簡単です:

SELECT a.field, a.start, a.end
FROM a
LEFT JOIN b
ON a.field = b.field AND NOT(a.start > b.end OR b.start > a.end)
WHERE b.field is NULL;

しかし、それらが重なっている場所、または b が a を 2 つのレコードに分割する場所はどうでしょうか? c日付範囲をタイムラインとして表示し、以下に示す関係を取得するにはどうすればよいですかa-b=c(線は、テーブル内の個々のレコードの日付範囲を表し、a結果bセットc)

a: |-----------------|    |--------|  |--------||-----|
b:        |---|                  |--------|
c: |-----|     |-----|    |-----|          |---||-----|

または、さらに良いことに、これらのクエリを簡素化するために使用できる、私が知らないライブラリ、拡張機能、コマンド、またはその他のソリューションはありますか? 面倒な日付範囲操作を処理できるものはありますか?

4

2 に答える 2

2

いくつかのポインタ:

  • 値が UTC に基づくタイムスタンプであるか、カレンダー全体の日付のみであることを確認してください。これは、タイム ゾーンと夏時間の問題を回避するためです。

  • 半開区間を使用してください[start, end)。これにより、2 つの隣接する範囲に同じ値が含まれるという問題が回避されます。言い換えると:

    • start <= value < end
    • start <= value && end > value

  • Noda Timeの使用を検討してください。それをIntervalよく表しているタイプです。ただし、現在、定義されている操作はあまり多くありません。

  • 膨大な数の操作が定義されているTime Period Library for .NETの使用を検討することもできます。一緒に使用するすべての値がその値を持っていることに注意してください。Local kind を使用しようとすると、正しく動作しません。つまり、合格しないでください。DateTimeDateTimeKind.Utc.KindDateTime.Now

  • もちろん、ライブラリを使用する必要はありません。独自の構造体またはクラスをいつでも定義して、範囲を含めることができます。このために組み込まれているものは何もありません。

  • 作成したクエリは重複を検出するのに適していますが、少し単純化することをお勧めします。

    これの代わりに: 次のようにNOT(a.start > b.end OR b.start > a.end)
    します: a.start < b.end AND b.start < a.end

    これは論理的には同等ですが、クエリとしてのパフォーマンスはわずかに向上します。

しかし、あなたの質問に直接答える方法がわかりません。あなたが何を求めているのかははっきりしていません。具体的には、最後の例で、 の 2 つの範囲がc既にテーブルに存在していて、それらを返したいですか? それとも、a と b の間の計算からそれらを構築したいですか? 後者の場合は、その部分を SQL ではなく C# で行うのがおそらく最善です。

于 2013-09-10T18:06:29.050 に答える
0

Time Period Library for .NETを使用すると、期間をコレクションに読み込み、 TimeGapCalculatorTimePeriodCombinerまたはTimePeriodSubtractorユーティリティを適用して、必要なギャップとオーバーラップを評価できます。

于 2013-09-13T13:18:07.297 に答える