Gegeben zwei Tabellen:
CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Ich möchte eine Abfrage schreiben , dass die Renditen Werte für ts
, foo
und bar
dass eine einheitliche Sicht auf die jüngsten Werte darstellt. Mit anderen Worten, falls foo
enthalten:
ts | foo
--------
1 | A
7 | B
und bar
enthielt:
ts | bar
--------
3 | C
5 | D
9 | E
Ich möchte eine Abfrage, die Folgendes zurückgibt:
ts | foo | bar
--------------
1 | A | null
3 | A | C
5 | A | D
7 | B | D
9 | B | E
Wenn beide Tabellen gleichzeitig ein Ereignis haben, spielt die Reihenfolge keine Rolle.
Ich konnte die benötigte Struktur mit union all und Dummy-Werten erstellen:
SELECT ts, foo, null as bar FROM foo
UNION ALL SELECT ts, null as foo, bar FROM bar
Das gibt mir eine lineare Zeitleiste mit neuen Werten, aber ich bin nicht in der Lage, die Nullwerte basierend auf den vorherigen Zeilen zu füllen. Ich habe die lag
Fensterfunktion ausprobiert , aber AFAICT wird nur die vorherige Zeile angezeigt, nicht rekursiv rückwärts. Ich habe rekursive CTEs untersucht, bin mir jedoch nicht ganz sicher, wie die Start- und Beendigungsbedingungen eingerichtet werden sollen.
quelle
foo
undbar
streng an oder ist der Testfall in dieser Hinsicht irreführend?Antworten:
Verwenden Sie eine
FULL [OUTER] JOIN
, kombiniert mit zwei Runden von Fensterfunktionen :Da
count()
NULL-Werte nicht gezählt werden, nimmt der Wert nur mit jedem Nicht-Null-Wert zu, wodurch Gruppen gebildet werden, die denselben Wert haben. In den äußerenSELECT
,min()
(odermax()
) ignoriert ebenfalls Nullwerte, um dadurch den eine Nicht-Null - Wert pro Gruppe Kommissionieren. Voilá.Zugehöriger
FULL JOIN
Fall:Dies ist einer der Fälle, in denen eine prozedurale Lösung möglicherweise schneller ist, da die Aufgabe mit einem einzigen Scan erledigt werden kann. Wie diese plpgsql Funktion :
Anruf:
db <> fummeln hier und demonstrieren beides.
Verwandte Antwort zur Erläuterung der
#variable_conflict use_column
:quelle
coalesce
ähnlichen Fensterfunktion.EXPLAIN ANALYZE
, das beste von 5 ...?IGNORE NULLS
(wie Oracle: sqlfiddle.com/#!4/fab35/1 ).''
und NULL nicht erkennen.