Dadas dos tablas:
CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Me gustaría escribir una consulta que devuelve los valores para ts
, foo
y bar
que representa una visión unificada de los valores más recientes. En otras palabras, si está foo
contenido:
ts | foo
--------
1 | A
7 | B
y bar
contenía:
ts | bar
--------
3 | C
5 | D
9 | E
Quiero una consulta que devuelva:
ts | foo | bar
--------------
1 | A | null
3 | A | C
5 | A | D
7 | B | D
9 | B | E
Si ambas tablas tienen un evento al mismo tiempo, el orden no importa.
He podido crear la estructura necesaria usando union all y valores ficticios:
SELECT ts, foo, null as bar FROM foo
UNION ALL SELECT ts, null as foo, bar FROM bar
lo que me dará una línea de tiempo lineal de nuevos valores, pero no soy capaz de resolver cómo llenar los valores nulos en función de las filas anteriores. He probado la lag
función de ventana, pero AFAICT sólo se verá en la fila anterior, no recursiva hacia atrás. He examinado los CTE recursivos, pero no estoy muy seguro de cómo configurar las condiciones de inicio y finalización.
fuente
foo
ybar
estrictamente ascendente en el tiempo o en el caso de prueba engañosa a este respecto?Respuestas:
Use a
FULL [OUTER] JOIN
, combinado con dos rondas de funciones de ventana :Como
count()
no cuenta los valores NULL, convenientemente solo aumenta con cada valor no nulo, formando así grupos que compartirán el mismo valor. En el exteriorSELECT
,min()
(omax()
) también ignora los valores NULL, eligiendo así el valor no nulo por grupo. VoiláFULL JOIN
Caso relacionado :Es uno de esos casos en los que una solución de procedimiento podría ser más rápida, ya que puede hacer el trabajo en un solo escaneo. Como esta función plpgsql :
Llamada:
db <> violín aquí , demostrando ambos.
Respuesta relacionada que explica el
#variable_conflict use_column
:fuente
coalesce
función de ventana similar.EXPLAIN ANALYZE
, mejor de 5 ...?IGNORE NULLS
(como Oracle lo ha hecho: sqlfiddle.com/#!4/fab35/1 ).''
y NULL.