Chr*_*rie 5 postgresql join window-functions
这个问题是我之前提出的一个过于简化的问题的扩展。更准确的示例在此 SQLFiddle中演示,我演示了一个有效(但速度较慢)的解决方案,然后尝试将先前的答案调整为实际问题。
实际问题是因为这两个表包含多个时间线的事件。
CREATE TABLE foo (ts int, id text, foo text);
INSERT INTO foo (ts, id, foo)
VALUES
(1, 'A', 'Lorem'),
(1, 'B', 'ipsum'),
(4, 'B', 'dolor'),
(5, 'A', 'sit'),
(8, 'A', 'amet'),
(8, 'B', 'consectetur');
CREATE TABLE bar (ts int, id text, bar text);
INSERT INTO bar (ts, id, bar)
VALUES
(1, 'A', 'adipiscing'),
(5, 'B', 'elit'),
(6, 'A', 'sed'),
(9, 'B', 'do ');
Run Code Online (Sandbox Code Playgroud)
每个表都有时间线“A”和“B”的事件。目标是将结果组合成单个结果集,显示每个时间线的“状态”。两条时间线是正交的。
ts id foo 栏 1 Lorem adipiscing 5 坐姿 6 A坐sed 8 Amet sed 1 B ipsum(空) 4 Bdolor(空) 5 B多洛尔精英 8 B consectetur 精英 9 B consectetur do
除了简单情况的解决方案之外,还在PARTITION
内部查询中的窗口函数中添加一个子句,以获取每个分区(每个“时间线”)的组编号。将组编号与相应的时间线(id
在您的示例中)结合起来,在第二步中保持分区分开:
SELECT id, ts
, min(foo) OVER (PARTITION BY id, foo_grp) AS foo
, min(bar) OVER (PARTITION BY id, bar_grp) AS bar
FROM (
SELECT id, ts, f.foo, b.bar
, count(f.foo) OVER (PARTITION BY id ORDER BY ts) AS foo_grp
, count(b.bar) OVER (PARTITION BY id ORDER BY ts) AS bar_grp
FROM foo f
FULL JOIN bar b USING (id, ts)
) sub
ORDER BY 1, 2;
Run Code Online (Sandbox Code Playgroud)
结果按要求(第一个除外id
)。
SQL小提琴
您对先前解决方案的尝试非常接近。它不起作用,因为/PARTITION BY f.id
而不是PARTITION BY b.id
PARTITION BY id
。您确实希望组合 id
结果中包含缺失的行 - 这就是必须为缺失 (NULL) 值填充最后一个非空值的位置。
如果性能是您的首要要求,请考虑使用服务器端功能,如上一个答案中所示。
归档时间: |
|
查看次数: |
948 次 |
最近记录: |