Соединения с 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