我有几个包含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)
找到真正的“有效”窗口。表:foo
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
... | ... | ... | ... | ... | ... | ... | ... | ... | ...
实现这一目标的最佳方法是什么?我已经创建了一个显示两种不同解决方案的fiddle,我希望听到关于每种解决方案的想法以及不在小提琴中的可能解决方案。
在该示例中,只需要连接两个表...但是,在某些情况下,我可能需要连接多个表3,4或更多。
使用选项#1 ,我的问题是,当我有大型结果集时,我发现初始子查询可能很大而postgres不能使用索引。这会导致大的性能损失。另一方面,我发现它是最准确的,因为我可以LEFT OUTER JOIN
反对它并获得相关的NULL
数据。
使用选项#2 ,查询计划程序可以使用TIMESTAMP WITH TIME ZONE
列上的索引;但是,在FROM
子句中加入两个以上的表变得更加复杂。我可以将(table1.start, table1.stop) OVERLAPS (table2.start, table2.stop)
移到WHERE
子句中,但随后我会丢失相关的NULL
数据。
所有这些让我想知道是否有更好的方法......
答案 0 :(得分:1)
lead()
和滞后()的默认值,而不是coalesce()
。
lead(datetime, 1, 'infinity') OVER (ORDER BY fooid, datetime) AS stop
而不是
COALESCE(LEAD(datetime) OVER (ORDER BY fooid, datetime), 'infinity'::TIMESTAMP) AS stop
PARTITION BY fooid
ORDER BY fooid
PARTITION BY fooid ORDER BY datetime
而不是:
(PARTITION BY fooid ORDER BY fooid, datetime)
除此之外:您的问题