Даны две таблицы:
CREATE TABLE foo (ts timestamp, foo text);
CREATE TABLE bar (ts timestamp, bar text);
Я хочу написать запрос, который возвращает значения для ts
, foo
и bar
который представляет собой единое представление самых последних значений. Другими словами, если foo
содержится:
ts | foo
--------
1 | A
7 | B
и bar
содержит:
ts | bar
--------
3 | C
5 | D
9 | E
Я хочу запрос, который возвращает:
ts | foo | bar
--------------
1 | A | null
3 | A | C
5 | A | D
7 | B | D
9 | B | E
Если в обеих таблицах одновременно происходит событие, порядок не имеет значения.
Я смог создать необходимую структуру, используя объединение всех и фиктивные значения:
SELECT ts, foo, null as bar FROM foo
UNION ALL SELECT ts, null as foo, bar FROM bar
что даст мне линейную шкалу времени новых значений, но я не совсем могу понять, как заполнить нулевые значения на основе предыдущих строк. Я пробовал lag
оконную функцию, но AFAICT будет смотреть только на предыдущий ряд, а не рекурсивно назад. Я смотрел на рекурсивные CTE, но я не совсем уверен, как настроить условия начала и завершения.
postgresql
join
window-functions
Кристофер Керри
источник
источник
foo
иbar
строго возрастают с течением времени или тестовый пример вводит в заблуждение в этом отношении?Ответы:
Используйте
FULL [OUTER] JOIN
, в сочетании с двумя раундами оконных функций :Поскольку
count()
значения NULL не учитываются, удобно увеличиваться только с каждым ненулевым значением, тем самым формируя группы с одинаковым значением. Во внешнемSELECT
,min()
(илиmax()
) также игнорирует значения NULL, тем самым выбирая значение один ненулевой для каждой группы. Вуаля.Родственный
FULL JOIN
случай:Это один из тех случаев, когда процедурное решение может быть просто быстрее, поскольку оно может выполнить работу за одно сканирование. Как эта функция plpgsql :
Вызов:
ДБ <> возиться здесь , демонстрируя оба.
Соответствующий ответ, объясняющий
#variable_conflict use_column
:источник
coalesce
подобной оконной функции.EXPLAIN ANALYZE
лучше 5 ...?IGNORE NULLS
(как Oracle: sqlfiddle.com/#!4/fab35/1 ).''
NULL от разницы .