Étant donné deux tableaux:
CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Je voudrais écrire une requête que les valeurs de rendements pour ts
, foo
et bar
qui représente une vue unifiée des valeurs les plus récentes. En d'autres termes, s'ils sont foo
contenus:
ts | foo
--------
1 | A
7 | B
et bar
contenait:
ts | bar
--------
3 | C
5 | D
9 | E
Je veux une requête qui renvoie:
ts | foo | bar
--------------
1 | A | null
3 | A | C
5 | A | D
7 | B | D
9 | B | E
Si les deux tables ont un événement en même temps, l'ordre n'a pas d'importance.
J'ai pu créer la structure nécessaire en utilisant l'union tout et les valeurs fictives:
SELECT ts, foo, null as bar FROM foo
UNION ALL SELECT ts, null as foo, bar FROM bar
ce qui me donnera une chronologie linéaire de nouvelles valeurs, mais je ne suis pas tout à fait capable de déterminer comment remplir les valeurs nulles en fonction des lignes précédentes. J'ai essayé la lag
fonction de fenêtre, mais AFAICT ne regardera que la ligne précédente, pas récursivement en arrière. J'ai examiné les CTE récursifs, mais je ne sais pas trop comment configurer les conditions de début et de fin.
la source
foo
-ellesbar
strictement croissantes dans le temps ou le scénario de test est-il trompeur à cet égard?Réponses:
Utilisez un
FULL [OUTER] JOIN
, combiné avec deux séries de fonctions de fenêtre :Étant donné
count()
que ne compte pas les valeurs NULL, il augmente commodément uniquement avec chaque valeur non nulle, formant ainsi des groupes qui partagent la même valeur. À l'extérieurSELECT
,min()
(oumax()
) ignore également les valeurs NULL, sélectionnant ainsi la seule valeur non nulle par groupe. Voilá.FULL JOIN
Cas connexe :C'est l'un de ces cas où une solution procédurale pourrait être plus rapide, car elle peut faire le travail en une seule analyse. Comme cette fonction plpgsql :
Appel:
db <> joue ici , démontrant les deux.
Réponse connexe expliquant
#variable_conflict use_column
:la source
coalesce
fonction de fenêtre de type.EXPLAIN ANALYZE
, le meilleur de 5 ...?IGNORE NULLS
(comme Oracle l'a: sqlfiddle.com/#!4/fab35/1 ).''
et NULL.