Postgresql
將多個時間線的兩個事件表合併到一個結果集中
這個問題是我之前提出的一個過於簡化的問題的擴展。這個 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 ');
每個表都有時間線“A”和“B”的事件。目標是將結果組合到一個結果集中,顯示每個時間線的“狀態”。兩條時間線是正交的。
ts id 富吧 1 客戶 5. 客戶是 6 坐 sed 8 擁抱 1 B 本身(空) 4 B dolor(空) 5 B 止痛藥 8乙 9 B 做
除了簡單案例的解決方案外,在內部查詢中的視窗函式中添加一個
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;
結果按要求(
id
第一個除外)。您嘗試適應以前的解決方案非常接近。由於
PARTITION BY f.id
/PARTITION BY b.id
而不是PARTITION BY id
. 您真的希望組合id
在結果中包含缺失的行 - 這就是必須為缺失 (NULL) 值填寫最後一個非空值的地方。如果性能是您的首要要求,請考慮使用上一個答案中展示的伺服器端功能。