Étudions enfin les autres options des jointures SQL2 (NATURAL JOIN, USING et CROSS JOIN).
Considérons le schéma suivant (des colonnes portent le même nom). La colonne typeAv dans la table Navigant désigne le type d’appareil sur lequel le pilote est instructeur.
Opérateur NATURAL JOIN
La jointure naturelle est programmée par la clause NATURAL JOIN. La clause de jointure est automatiquement construite sur la base de toutes les colonnes portant le même nom entre les deux tables.
Les concepteurs devraient ainsi penser à nommer d’une manière semblable clés primaires et clés étrangères ! Ce principe n’est pas souvent appliqué aux bases volumineuses.
Le tableau suivant détaille deux écritures possibles d’une jointure naturelle. La clause de join-ture est basée sur les colonnes (brevet, typeAv). Une clause WHERE aurait pu aussi être progammée.
Figure 4-20 Deux tables à mettre en jointure naturelle
Navigant
brevet nom nbHVol typeAv
PL-1 Pierre Lamothe 450 PL-2 Didier Linxe 900 A320 PL-3 Henri Alquié 3400 A380
VolsControle
brevet typeAv validite PL-1 A320 2005-06-24 PL-2 A320 2006-04-04 PL-2 A330 2006-05-13 PL-3 A380 2007-07-20 PL-3 A320 2005-03-12
Tableau 4-47 Jointures naturelles
Besoin Jointures SQL2 et résultat
Navigants qualifiés sur un type d’appareil et instructeurs sur ce même type.
SELECT brevet, nom, typeAv, validite
FROM Naviguant ;
--équivalent à
SELECT brevet, nom, typeAv, validite
FROM VolsControle ;
NATURAL JOIN VolsControle
NATURAL JOIN Naviguant
Opérateur USING
La directive USING(col1, col2…) de la clause JOIN programme une jointure naturelle res-treinte à un ensemble de colonnes. Il ne faut pas utiliser d’alias de tables dans la liste des colonnes.
Dans notre exemple, on peut restreindre la jointure naturelle aux colonnes brevet ou typeAv. Si on les positionnait (brevet, typeAv) dans la directive USING, cela reviendrait à construire un NATURAL JOIN. Le tableau suivant détaille deux écritures d’une jointure naturelle restreinte :
Opérateur CROSS JOIN
La directive CROSS JOIN programme un produit cartésien qu’on peut restreindre dans la clause WHERE.
+---+---+---+---+
| brevet | nom | typeAv | validite | +---+---+---+---+
| PL-2 | Didier Linxe | A320 | 2006-04-04 |
| PL-3 | Henri Alquié | A380 | 2007-07-20 | +---+---+---+---+
Tableau 4-47 Jointures naturelles (suite)
Besoin Jointures SQL2 et résultat
Tableau 4-48 Jointures naturelles restreintes
Besoin Jointures SQL2 et résultat
Nom des navigants avec leurs qualifications et dates de validité.
SELECT nom, v.typeAv, v.validite FROM Naviguant
;
SELECT nom, v.typeAv, v.validite FROM VolsControle v
; +---+---+---+
| nom | typeAv | validite | +---+---+---+
| Pierre Lamothe | A320 | 2005-06-24 |
| Didier Linxe | A320 | 2006-04-04 |
| Didier Linxe | A330 | 2006-05-13 |
| Henri Alquié | A380 | 2007-07-20 |
| Henri Alquié | A320 | 2005-03-12 | +---+---+---+
Web
JOIN VolsControle v USING(brevet)
JOIN Naviguant USING(brevet)
Le tableau suivant présente deux écritures d’un produit cartésien (seul l’ordre d’affichage des colonnes change) :
Division
La division est un opérateur algébrique et non ensembliste. Cet opérateur est semblable sur le principe à l’opération qu’on apprend au CM2 (oubliée plus tard en terminale à cause des calculettes). La division est un opérateur binaire comme la jointure, car il s’agit de diviser une table (ou partie de) par une autre table (ou partie de). Il est possible d’opérer une division à partir d’une seule table, en ce cas on divise deux parties de cette table (analogue aux autojoin-tures).
L’opérateur de division n’est pas fourni par MySQL (ni par aucun de ses concurrents d’ailleurs).
Il n’existe donc malheureusement pas d’instruction DIVIDE.
Est-ce la complexité ou le manque d’intérêt qui freinent les éditeurs de logiciels à programmer ce concept ? La question reste en suspens, alors si vous avez un avis à ce sujet, faites-moi signe !
Cet opérateur permet de traduire le terme « pour tous les » des requêtes qu’on désire pro-grammer en SQL.
On peut aussi dire que lorsque vous voulez comparer un ensemble avec un groupe de réfé-rence, il faut programmer une division.
La division peut se programmer sous MySQL à l’aide d’une différence (NOT IN) et la fonction NOT EXISTS.
Tableau 4-49 Produit cartésien
Besoin Jointures SQL2 et résultat
Combinaison de toutes les lignes des deux tables.
SELECT * FROM Naviguant ;
-- équivalent à
SELECT * FROM VolsControle
+---+---+---+---+---+---+---+
| brevet | nom | nbHVol | typeAv | brevet | typeAv | validite | +---+---+---+---+---+---+---+
| PL-1 | Pierre Lamothe | 450.00 | NULL | PL-1 | A320 | 2005-06-24 |
| PL-2 | Didier Linxe | 900.00 | A320 | PL-1 | A320 | 2005-06-24 |
| PL-3 | Henri Alquié | 3400.00 | A380 | PL-1 | A320 | 2005-06-24 |
| PL-1 | Pierre Lamothe | 450.00 | NULL | PL-2 | A320 | 2006-04-04 | ...
15 rows in set
Web CROSS JOIN VolsControle
CROSS JOIN Naviguant;
La figure suivante illustre l’opérateur de division dans sa plus simple expression (je ne parle pas du contenu des tables, bien sûr…). Le schéma fait plus apparaître le deuxième aspect révé-lateur énoncé ci-avant, à savoir comparer un ensemble (la table T1) avec un ensemble de réfé-rence (la table T2).
Définition
La division de la table T1[a1,...,an,b1,...,bn] par la table T2[b1,...,bn] (la structure de T2 est incluse dans la structure de T1) donne la table T3[a1,...,an] qui contient les enregistrements ti vérifiant ti ∈ T3 (de structure [a1,...,an]), tj ∈ T2 (tj de structure [b1,...,bn]) et ti,tj ∈ T1 (ti,tj de structure [a1,...,an,b1,...,bn]).
Classification
Considérons l’exemple suivant pour décrire la requête à construire. Il s’agit de répondre à la question : « Quels sont les avions affrétés par toutes les compagnies françaises ? ». L’ensem-ble de référence (A) est constitué des codes des compagnies françaises. L’ensemL’ensem-ble à compa-rer (B) est formé des codes des compagnies pour chaque avion.
Deux cas sont à envisager suivant la manière de comparer les deux ensembles :
● Division inexacte (le reste n’est pas nul) : un ensemble est seulement inclus dans un autre (A ∈ B). La question à programmer serait : « Quels sont les avions affrétés par toutes les compagnies françaises ? », sans préciser si les avions ne doivent pas être aussi affrétés par des compagnies étrangères. L’avion ('A3', 'Mercure') répondrait à cette question, que la dernière ligne de la table Affretements soit présente ou pas.
● Division exacte (le reste est nul) : les deux ensembles sont égaux (B=A). La question à programmer serait : « Quels sont les avions affrétés exactement (ou uniquement) par toutes les compagnies françaises ? ». L’avion ('A3', 'Mercure') répondrait à cette question si la dernière ligne de la table Affretements était inexistante. Les lignes concernées dans les deux tables sont grisées.
Figure 4-21 Division T1
Jospin Juppé Juppé Baudis Baudis Baudis Chirac Chirac Chirac
T2
Quotient Chirac
Quels sont les enregistrements de T1 qui sont associés à « tous les » enregistrements de T2? Réponse : Chirac
Quotient=(T1–Reste)/T2 (ici Reste n’est pas nul)
L’opérateur de différence (programmé avec NOT IN) combiné à la fonction EXISTS permet de programmer ces deux comparaisons (un ensemble inclus dans un autre et une égalité d’ensembles). Il existe d’autres solutions à base de regroupements et de sous-interrogations (synchronisées ou pas) que nous n’étudierons pas, parce qu’elles me semblent plus compli-quées. Écrivons à présent ces deux divisions à l’aide de requêtes SQL.