Connexions aux tables dérivées LATERAL
.
Une table dérivée définie avec le mot-clé LATERAL
est appelée table dérivée latérale. Si une table dérivée est définie comme une table latérale, elle est autorisée à faire référence à d'autres tables dans la même clause FROM
, mais seulement à celles déclarées plus tôt dans la clause FROM. Sans LATERAL
, chaque sous-requête est exécutée indépendamment et ne peut donc pas faire référence à d'autres éléments FROM
.
L'élément LATERAL
peut se trouver au niveau supérieur de la liste FROM
ou dans l'arbre JOIN
. Dans ce dernier cas, il peut également être lié à tout élément situé à gauche du JOIN à droite duquel il se trouve.
Lorsqu'un élément FROM
contient des références LATERAL
, alors la requête est exécutée de la manière suivante : d'abord les valeurs de toutes les colonnes dont dépend la table dérivée avec le mot-clé LATERAL
, puis la table dérivée elle-même avec LATERAL
pour chaque enregistrement résultant est calculée. Les lignes obtenues à partir de la table dérivée avec LATERAL
sont jointes avec les lignes dont elles sont dérivées.
Les jointures suivantes sont autorisées : CROSS JOIN
et LEFT OUTER JOIN
. Une jonction interne est également autorisée, mais n'est pas recommandée car des problèmes peuvent survenir lors du calcul de la condition de jonction des fils.
A titre d'exemple, imprimez les résultats des chevaux et leurs dernières mesures. Si un cheval n'a pas de mensurations, il ne sera pas sorti :
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
une autre façon d'écrire cette demande
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
Si vous voulez sortir les chevaux sans tenir compte du fait qu'ils ont au moins une mesure, vous devez remplacer CROSS JOIN
par 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