Sous-requêtes corrélées dans Invantive UniversalSQL

Une sous-requête peut maintenant utiliser une colonne de la requête environnante.

Cela rend disponible dans Invantive UniversalSQL une manière courante de décrire “la ligne qui correspond à cette ligne”, comme dans l’exemple ci-dessous. Jusqu’à présent, une telle sous-requête indiquait que la colonne était inconnue.

Fonctionnement

Une sous-requête recherche un nom d’abord parmi ses propres sources de données. Ce n’est que si elle ne connaît pas le nom qu’elle consulte la requête environnante, et ensuite la requête au-delà. Un nom existant aux deux endroits se réfèrera donc à celui le plus proche. Ajouter une colonne à une table ne peut donc pas changer la signification d’une sous-requête existante.

Une corrélation peut atteindre n’importe combien de niveaux vers l’extérieur et peut sauter un niveau. Une sous-requête située à deux niveaux de profondeur peut utiliser une colonne de la requête extérieure sans que la requête intermédiaire ne joue un rôle.

La corrélation est autorisée dans les mêmes formes qu’une sous-requête sans corrélation : exists et not exists, in et not in, et la sous-requête scalaire. Cette dernière produit une seule valeur et peut être utilisée partout où une expression est permise, donc aussi dans la liste de sélection, dans un calcul et dans un case.

Exemple : Y a-t-il une Ligne Correspondante

L’exemple suivant sélectionne les employés dont le département figure dans le deuxième jeu de données. La sous-requête utilise emp.dept, une colonne de la requête environnante :

select emp.code
from   ( select 'A100' code, 'SLS' dept
         union all
         select 'A200' code, 'ENG' dept
       ) emp
where  exists ( select 1
                from   ( select 'SLS' dept
                       ) dpt
                where  dpt.dept = emp.dept
              )

Cela renvoie une ligne avec la valeur A100. L’employé A200 travaille dans un département que le deuxième ensemble ne connaît pas.

Exemple : Une Valeur Par Ligne

Une sous-requête scalaire dans la liste de sélection compte les lignes qui correspondent à chaque employé :

select emp.code
,      ( select count(*)
         from   ( select 'A100' code
                  union all
                  select 'A100' code
                ) ord
         where  ord.code = emp.code
       ) orders
from   ( select 'A100' code
         union all
         select 'A200' code
       ) emp

Cela donne A100 avec 2 et A200 avec 0. Un count sur aucune ligne correspondante est zéro. Toute autre agrégation, comme max ou sum, donnera dans cette situation la valeur vide.

Valeurs Vides

Une comparaison avec une valeur vide n’a aucun résultat, et ce résultat diffère selon la forme. Avec exists, une ligne qui se compare avec une valeur vide n’est pas une correspondance, de sorte que la sous-requête ne trouve rien. Avec not in, une seule valeur vide parmi les valeurs fournies rend la réponse indécise, ce qui empêche la ligne d’être livrée. Cela vaut aussi si la valeur comparée est elle-même vide.

Nombre de Demandes à la Plateforme

Une sous-requête corrélée est réécrite en une jointure pour l’exécution. Chaque source de données est donc lue un nombre fixe de fois, quel que soit le nombre de lignes de la requête environnante.

Sans cette réécriture, la sous-requête serait exécutée une fois par ligne, ce qui, sur une plateforme accessible via le cloud, signifierait une demande par ligne.

Limitation

Une sous-requête dans un order by n’est pas encore prise en charge.

Disponibilité

Les sous-requêtes corrélées sont disponibles à partir de la version 27.0 pour toutes les plateformes.

Voir aussi