Langage Manipulation de Données 2 : requêtes imbriquées
2025-09-26
Les deux tables doivent avoir des schémas identiques
EXCEPT`Fournisseur (NomF, VilleF, AdresseF)`
`Piece(NomP, Prix, Couleur)`
`Livraison(NumLiv, NomP, NomF, DateLiv, Quantite)`Fournisseurs qui ont livré la pièce x22 mais pas la pièce x21
IN, EXISTS, ALL, ANY, LATERALLe résultat d’une requête SQL est un ensemble de tuples… donc une relation.
Dans la clause WHERE d’une requête, on peut utiliser une fonction d’une autre requête, appelée sous-requête
IN, EXISTS, ALL, ANY sont des fonctions qui prennent une sous-requête (une relation) en argument.
Dans une sous-requête, on peut se référer à des attributs des tables de la clause FROM.
Pour chaque ligne d’un item FROM qui fournit la colonne référencée, l’item LATERAL est évalué en utilisant cette ligne. Les lignes du résultat sont jointes avec la ligne qui a servi à les calculer.
On peut utiliser ces résultats comme données d’une autre requête
Moyens : utiliser des fonctions de table dans la clause WHERE.
INOpérateur IN déjà vu pour exprimer que l’attribut est à valeur dans une certaine liste
Nouvelle utilisation de IN avec des sous-requêtes.
Evaluée à vraie si
INLister les villes de fournisseurs qui ont livré la pièce ‘x21’.
INLister les couleurs de pièces livrées par des fournisseurs de Paris
INUtilisation ci-dessus pas très utile mais…
Pratique à utiliser sous la forme NOT IN
Lister les noms de pièces qui n’ont jamais été livrées.
Equivalence en algèbre relationnelle :
\[\pi_{\text{NomP}}(\text{Piece}) - \pi_{\text{NomP}}(\text{Livraison})\]
…. Une des façons de coder la différence en SQL
INLes capitales dont la population est plus grande que la moitié de la population du pays
ANY, ALLDeux nouveaux opérateurs manipulant des sous-requêtes : ANY, ALL
évaluée à vraie si au moins un des résultats de la sous requête vérifie la comparaison avec <attributs>
évaluée à vraie si tous les résultats de la sous-requête vérifient la comparaison avec <attributs>
<attributs>: peut être une liste d’attributs
ANY, ALLAlternative au IN
lister les noms de fournisseurs qui ont livré la pièce ‘x21’.
ANY, ALLInformation sur la commande dont la quantité de ièces livrées était la plus importante.
ANY, ALLNoms et prix des pièces livrées les plus chères
ANY, ALLLa ville la plus peuplée de chaque pays
EXISTSest évaluée à vraie si la sous-requête renvoie au moins un résultat.
Nom et prix des pièces qui ont été livrées
Différence avec ANY
L’utilisation de EXISTS s’apparente à une condition booléenne.
Pas de test sur la valeur d’un attribut particulier.
EXISTSNom des Fournisseurs ayant livré la pièce x21 mais qui n’ont jamais livré la pièce a22.
EXISTSLes régions qui ont au moins une langue officielle :
PostgreSQL 9.3 has a new join type! Lateral joins arrived without a lot of fanfare, but they enable some powerful new queries that were previously only tractable with procedural code. In this post, I’ll walk through a conversion funnel analysis that wouldn’t be possible in PostgreSQL 9.2.
LATERALImportant
Les sous-requêtes d’une clause FROM peuvent être précédées du mot-clé LATERAL
On peut alors faire référence à des colonnes des éléments précédents de la clause FROM
When a FROM item contains
LATERALcross-references, evaluation proceeds as follows: for each row of theFROMitem providing the cross-referenced column(s), or set of rows of multipleFROMitems providing the columns, theLATERALitem is evaluated using that row or row set’s values of the columns. The resulting row(s) are joined as usual with the rows they were computed from. This is repeated for each row or set of rows from the column source table(s).
Les arguments de la fonction peuvent contenir des références à des colonnes des items précédents de la clause FROM.
Pour chaque ligne d’un item FROM qui fournit la colonne référencée, l’item LATERAL est évalué en utilisant cette ligne. Les lignes du résultat sont jointes avec la ligne qui a servi à les calculer
On peut parler de sous-requête paramétrée
LATERALSELECT name_country, name_city
FROM country, LATERAL (
SELECT name_city
FROM city
WHERE city.countrycode=country.countrycode
) ss
ORDER BY name_country;équivalent à
LATERAL est surtout utilisé quand la colonne référencée est nécessaire au calcul des lignes à joindre
LATERAL en action sur world| name_country | name_city |
|---|---|
| Spain | A Coruña (La Coruña) |
| Germany | Aachen |
| Denmark | Aalborg |
| Nigeria | Aba |
| Iran | Abadan |
| Brazil | Abaetetuba |
| Russian Federation | Abakan |
| Canada | Abbotsford |
| Nigeria | Abeokuta |
| … | … |
SELECT name_country, name_city, lifeexpectancy
FROM (
SELECT countrycode, name_country, lifeexpectancy
FROM country
WHERE gnpold >0 AND gnp / gnpold > 1.1
) AS better_off
JOIN LATERAL (
SELECT c.countrycode, name_city #<<
FROM country c
JOIN city ON (capital = id)
WHERE
better_off.countrycode=c.countrycode AND
population_city> 2000000
) AS big_capital
ON TRUE ; | Country | City | Life expectancy |
|---|---|---|
| Iran | Teheran | 69.7 |
| Congo, The Democratic Republic of the | Kinshasa | 48.8 |
| Turkey | Ankara | 71.0 |
Could be useful for implementing exploratory pipelines into postgresql without to much tears and sweat.
WITHUne clause WITH permet d’écrire des requêtes intermédiaires et de décomposer une requête complexe
Ces expressions/requêtes sont souvent désignées par le vocable Common Table Expressions ou CTEs
Les CTEs (éléments d’une clasuse WITH) peuvent être des requêtes, mais aussi des expressions de manipulation (mise à jour, insertion, suppression) de données
Les CTEs permettent de coller plus fidèlement à l’algèbre relationnelle que les requêtes imbriquées
WITH better_off AS (
SELECT countrycode, name_country, lifeexpectancy, capital
FROM country
WHERE gnpold >0 AND gnp / gnpold > 1.1
),
big_capital AS (
SELECT id, countrycode
FROM city
WHERE population > 2000000
)
SELECT bo.countrycode, name_country, lifeexpectancy
FROM better_off bo JOIN big_capital bc ON
(bo.countrycode=bc.countrycode AND bc.id=bo.capital) ;
Requêtes SQL imbriquées

MA15Y030 – Bases de Données – L3 MIASHS – UParis Cité