Соединения с LATERAL
производными таблицами
Производная таблица, определенная с помощью ключевого слова LATERAL
, называется латеральной производной таблицей.Если производная таблица определена как латеральная, то разрешается ссылаться на другие таблицы в том же предложении FROM
, но только на те, которые были объявлены раньше в предложении FROM.Без LATERAL
каждый подзапрос выполняется независимо и поэтому не может обращаться к другим элементам FROM
.
Элемент LATERAL
может находиться на верхнем уровне списка FROM
или в дереве JOIN
.В последнем случае он может также ссылаться на любые элементы в левой части JOIN, справа от которого он находится.
Когда элемент FROM
содержит ссылки LATERAL
, то запрос выполняется следующим образом: сначала вычисляется значения всех столбцов о которых зависит производная таблица с ключевым словом LATERAL
, затем вычисляется сама производная таблица с LATERAL
для каждой полученной записи.Результирующие строки полученные из производной таблицы с LATERAL
соединяются со строками из которых они получены.
В качестве соединений допускается следующие CROSS JOIN
и LEFT OUTER JOIN
.Внутреннее соединение также допустимо, но не рекомендуется, поскольку могут возникнуть проблемы при вычислении условия соединения потоков.
В качестве примера выведем результаты лошадей и их последние промеры.Если у лошади нет ни одного промера, то она не будет выведена:
SELECT
HORSE.NAME,
M.BYDATE,
M.HEIGHT_HORSE,
M.LENGTH_HORSE
FROM HORSE
CROSS JOIN LATERAL(SELECT
*
FROM MEASURE
WHERE MEASURE.CODE_HORSE = HORSE.CODE_HORSE
ORDER BY MEASURE.BYDATE DESC
FETCH FIRST ROW ONLY) M
другой вариант написание этого запроса
SELECT
HORSE.NAME,
M.BYDATE,
M.HEIGHT_HORSE,
M.LENGTH_HORSE
FROM HORSE,
LATERAL(SELECT
*
FROM MEASURE
WHERE MEASURE.CODE_HORSE = HORSE.CODE_HORSE
ORDER BY MEASURE.BYDATE DESC
FETCH FIRST ROW ONLY) M
Если необходимо выводить лошадей, не зависимо есть ли у них хотя бы один промер, то необходимо заменить CROSS JOIN
на LEFT JOIN
:
SELECT
HORSE.NAME,
M.BYDATE,
M.HEIGHT_HORSE,
M.LENGTH_HORSE
FROM HORSE
LEFT JOIN LATERAL(SELECT
*
FROM MEASURE
WHERE MEASURE.CODE_HORSE = HORSE.CODE_HORSE
ORDER BY MEASURE.BYDATE DESC
FETCH FIRST ROW ONLY) M ON TRUE