TIMESTAMP WITH TIME ZONE
いくつかの追加情報とともに列を持つテーブルがいくつかあります。これらのテーブルを結合して、各行のすべての情報が特定の日時ウィンドウ (ラベル付けbegin
さend
れ、目的の結果セット内) の時点で「有効」になるようにする必要があります。
私の現在のアプローチ:
オプション1
- ユニークな時間のリストを作成します。
- 各時点を、一意のリスト (「有効な」時間ウィンドウ) および元の各テーブルの時間ウィンドウに変換します。[
LEAD(...) OVER (...)
] - 元のテーブルを一意の時間リストに結合します。
オプション #2
- 各時点 (
TIMESTAMP WITH TIME ZONE
) を各テーブルの時間枠に変換します。[LEAD(...) OVER (...)
] - ウィンドウが重なっているテーブルを結合します。
GREATEST(foo.start, bar.start)
各ウィンドウから&を返しLEAST(foo.stop, bar.stop)
て、真の「有効な」ウィンドウを見つけます。
例えば:
表:フー
fooid | description | datetime
---------|---------------|-----------------------
1 | Varsion 1 | 2010-01-01 00:00:00
2 | Varsion 2 | 2010-07-01 00:00:00
表:バー
barid | fooid | description | datetime
---------|---------|---------------|-----------------------
1 | 1 | Varsion A | 2010-01-01 00:00:00
2 | 1 | Varsion B | 2010-02-01 00:00:00
3 | 1 | Varsion C | 2010-03-01 00:00:00
4 | 1 | Varsion D | 2010-04-01 00:00:00
5 | 1 | Varsion E | 2010-05-01 00:00:00
6 | 1 | Varsion F | 2010-06-01 00:00:00
7 | 2 | Varsion A | 2010-07-01 00:00:00
8 | 2 | Varsion B | 2010-08-01 00:00:00
9 | 2 | Varsion C | 2010-09-01 00:00:00
10 | 2 | Varsion D | 2010-10-01 00:00:00
11 | 2 | Varsion E | 2010-11-01 00:00:00
12 | 2 | Varsion F | 2010-12-01 00:00:00
簡略化された望ましい結果
begin | end | fooid | foo_desc | foostart | foostop | barid | bar_desc | foostart | foostop
-----------------------|-----------------------|---------|---------------|-----------------------|-----------------------|---------|--------------|-----------------------|-----------------------
... | ... | ... | ... | ... | ... | ... | ... | ... | ...
2010-05-01 00:00:00 | 2010-06-01 00:00:00 | 1 | Varsion 1 | 2010-01-01 00:00:00 | 2010-07-01 00:00:00 | 5 | Varsion E | 2010-05-01 00:00:00 | 2010-06-01 00:00:00
2010-06-01 00:00:00 | 2010-07-01 00:00:00 | 1 | Varsion 1 | 2010-01-01 00:00:00 | 2010-07-01 00:00:00 | 6 | Varsion F | 2010-06-01 00:00:00 | infinity
2010-07-01 00:00:00 | 2010-08-01 00:00:00 | 2 | Varsion 2 | 2010-07-01 00:00:00 | infinity | 7 | Varsion A | 2010-07-01 00:00:00 | 2010-08-01 00:00:00
2010-08-01 00:00:00 | 2010-09-01 00:00:00 | 2 | Varsion 2 | 2010-07-01 00:00:00 | infinity | 8 | Varsion B | 2010-08-01 00:00:00 | 2010-09-01 00:00:00
... | ... | ... | ... | ... | ... | ... | ... | ... | ...
私の質問:
これを達成するための最良の方法は何ですか?私は 2 つの異なる解決策を示すフィドルを作成しました。それぞれのアイデアと、フィドルにない可能な解決策について聞きたいと思います。
更新 #1:
この例では、結合する必要があるテーブルは 2 つだけです...ただし、場合によっては、3 つ、4 つ、またはそれ以上の複数のテーブルを結合する必要があります。
更新 #2:
オプション #1を使用した場合、私の問題は、結果セットが大きい場合、最初のサブクエリが大きくなる可能性があり、postgres がインデックスを使用できないことです。これにより、パフォーマンスが大幅に低下します。一方、それに対してできる限り最も正確LEFT OUTER JOIN
であり、関連するNULL
データを取り戻すことができます.
オプション #2を使用すると、クエリ プランナーはTIMESTAMP WITH TIME ZONE
列のインデックスを使用できます。FROM
ただし、3 つ以上のテーブルを結合すると、節内でより複雑になります。句に移動できますが、関連する(table1.start, table1.stop) OVERLAPS (table2.start, table2.stop)
データが失われます。WHERE
NULL
これはすべて、より良い方法があるかどうか疑問に思います...