Tri de données avec le langage SQL
Introduction :
Nous savons ce qu'est une base de données relationnelle, nous savons aussi la mettre en œuvre et l'utiliser grâce au SGBD et au langage SQL. Nous achevons ce chapitre sur les bases de données avec un cours destiné à compléter nos connaissances sur les requêtes SQL.
Il s'agira ici d'apprendre à formuler des recherches plus élaborées, faisant appel à des fonctions de tri ou de calcul. Nous verrons également comment articuler une requête SQL touchant plusieurs tables à la fois. Commençons donc par nous pencher sur les fonctions de calcul et transformation auxquelles il est possible d'avoir recours dans une commande SQL.
Calculs et transformations dans une requête
Calculs et transformations dans une requête
À l'occasion d'une requête, il est possible de demander le résultat d'un calcul opéré sur la valeur d'une ou plusieurs colonnes pour chaque ligne concernée. On peut aussi demander le résultat d'un calcul qui porte sur l'ensemble des lignes d'une table. D'autres manipulations sont également possibles.
Calcul portant sur la valeur d'une colonne
Calcul portant sur la valeur d'une colonne
Le résultat d'un calcul effectué sur la valeur d'une colonne est stocké dans une colonne qui vient s'ajouter à la table résultat de la requête.
Ainsi, on peut effectuer des calculs impliquant une ou plusieurs colonnes en ayant recours aux opérateurs arithmétiques suivants :
addition | |
soustraction | |
multiplication | |
division | |
reste dans la division |
Nous voulons la liste des recettes du club, avec leur nom et leur durée en seconde. Il est donc nécessaire d'effectuer un calcul avec la colonne duree qui est exprimée et stockée en minutes dans la base de données. Voici la commande SQL qui en résulte :
La clause
permet de baptiser le nom de la nouvelle colonne destinée à recueillir le résultat du calcul.Voici la table recette :
idRecette | nomRecette | niveau | duree | categorie | idAdherent |
1 | Mayonnaise | difficile | 15 | sauce | 7 |
2 | Omelette | facile | 5 | plat | 6 |
3 | Pâte brisée | moyen | 20 | autre | 6 |
4 | Quatre-quarts | facile | 10 | dessert | 4 |
5 | Purée de carottes | moyen | 15 | accompagnement | 2 |
6 | Poulet rôti | facile | 15 | plat | 2 |
7 | Sole meunière | difficile | 20 | plat | 7 |
Le résultat obtenu est une table de deux colonnes :
nomRecette | dureeSecondes |
Mayonnaise | 900 |
Omelette | 300 |
Pâte brisée | 1200 |
Quatre-quarts | 600 |
Purée de carottes | 900 |
Poulet rôti | 900 |
Sole meunière | 1200 |
Calcul portant sur l'ensemble des lignes d'une table
Calcul portant sur l'ensemble des lignes d'une table
Entre autres calculs et transformations, penchons-nous sur les fonctions statistiques simples que l'on peut appeler avec SQL, recensées dans le tableau qui suit :
COUNT(*) | Nombre de lignes dans la table |
valeur maximum dans la colonne | |
valeur minimum dans la colonne | |
valeur moyenne de la colonne | |
somme des valeurs de la colonne |
Si l'on veut connaître la durée moyenne des recettes du club de cuisine, en minutes, on passera la commande SQL suivante au SGBD :
Le résultat alors retourné est une table d'une colonne et d'une ligne :
dureeMoyenne |
14.2857 |
Et si l'on souhaite connaître le nombre d'adhérent·e·s du club de cuisine, il suffira d’entrer la commande suivante :
Voici la table adherent :
idAdherent | nomAdherent | prenom | numero | rue | idVille | passe | telephone | |
1 | DURAND | Jacques | j.durand@orange.fr | 16b | rue brune | 1 | motdepass1 | 0601020304 |
2 | DUVAL | Paul | paul.d@sfr.fr | 135 | avenue rouge | 4 | motdepass2 | 0704030201 |
3 | DELORS | Sophie | sodelors@outlook.com | 22a | bd vert | 3 | motdepass3 | 0606060202 |
4 | VERGER | Jehan | jverger@aol.com | 4ter | impasse jaune | 5 | motdepass4 | 0601020102 |
5 | MONVILLE | Fleur | fleur1212@free.fr | 9 | sente aux loups | 2 | motdepass5 | 0707020201 |
6 | BRIARD | Paul | paul.briard27@hotmail.fr | 191 | rue violette | 4 | motdepass6 | 0612345678 |
7 | LÉGER | Marguerite | mag0506@perso.com | 17 | place noire | 3 | motdepass7 | 0687654321 |
8 | FLAMAND | Lise | flise@gmail.com | 329 | route bleue | 2 | motdepass8 | 0632323232 |
Et voici le résultat retourné, qui est une table d'une colonne et d'une ligne :
nbAdherents |
8 |
On remarquera au passage qu'on ne spécifie pas une colonne en particulier dans la fonction
puisqu'il s'agit de compter le nombre de toutes les lignes dans la table, sans s'intéresser à une colonne en particulier.Autres manipulations sur les données
Autres manipulations sur les données
D'autres transformations sur les colonnes sont possibles lors d'une requête d'interrogation, comme par exemple le passage en majuscule d'une colonne de type chaîne de caractères avec la fonction
. On peut également demander l'extraction du mois d'une date grâce à la fonction .Voici la requête permettant d'obtenir la liste des numéros, noms et prénoms des adhérent·e·s affichés en majuscules de notre club de cuisine :
Le résultat est une table de trois colonnes :
idAdherent | nomMaj | prenomMaj |
1 | DURAND | JACQUES |
2 | DUVAL | PAUL |
3 | DELORS | SOPHIE |
4 | VERGER | JEHAN |
5 | MONVILLE | FLEUR |
6 | BRIARD | PAUL |
7 | LEGER | MARGUERITE |
8 | FLAMAND | LISE |
Il peut être parfois intéressant d'effectuer des calculs statistiques portant sur des groupes de lignes et toutes les lignes d'une table. On aura alors recours à des opérations d'agrégation. Nous allons voir également que l'on peut exiger d'une requête qu'elle nous restitue sa table résultat de manière triée.
Agrégats et tri
Agrégats et tri
Calcul sur agrégats
Calcul sur agrégats
On effectue une opération dite d'agrégation pour regrouper les lignes d'une table par la même valeur qu'elles contiennent dans une colonne. L'objectif d'effectuer une agrégation est, en général, de pratiquer des calculs statistiques sur les groupes ainsi constitués.
La clause employée pour pratiquer une agrégation est
:
Notre club de cuisine souhaite connaître le nombre de recettes dans sa base pour chaque catégorie.
La table des recettes est la suivante :
idRecette | nomRecette | niveau | duree | categorie | idAdherent |
1 | Mayonnaise | difficile | 15 | sauce | 7 |
2 | Omelette | facile | 5 | plat | 6 |
3 | Pâte brisée | moyen | 20 | autre | 6 |
4 | Quatre-quarts | facile | 10 | dessert | 4 |
5 | Purée de carottes | moyen | 15 | accompagnement | 2 |
6 | Poulet rôti | facile | 15 | plat | 2 |
7 | Sole meunière | difficile | 20 | plat | 7 |
Il suffira donc de transmettre la requête SQL suivante au SGBD :
La table résultat qui nous sera alors retournée sera par conséquent :
categorie | nombre |
sauce | 1 |
plat | 3 |
autre | 1 |
dessert | 1 |
accompagnement | 1 |
Restriction sur le résultat d'un calcul sur agrégat
Restriction sur le résultat d'un calcul sur agrégat
On peut ajouter une opération de filtrage à la table résultant d'une opération sur agrégat. La clause
permet d'exprimer le critère de filtrage sur cette table résultat.Le club décide de recueillir les seules catégories de recette dont la durée moyenne est au moins de 14 minutes.
La commande SQL suivante nous permet de calculer la durée moyenne des recettes par catégorie :
La table résultat qui est restituée est ainsi :
categorie | dureeMoyenne |
sauce | 15.0000 |
plat | 13.3333 |
autre | 20.0000 |
dessert | 10.0000 |
accompagnement | 15.0000 |
En complétant la commande par la clause
, on ne retient que les catégories figurant dans la table résultat dont la colonne dureeMoyenne répond au critère du filtre :
Le résultat qui est restitué ne nous étonne pas :
categorie | dureeMoyenne |
sauce | 15.0000 |
autre | 20.0000 |
accompagnement | 15.0000 |
Tris
Tris
Lorsque l'on effectue une requête, par défaut, la table résultat qui est restituée n'est pas triée.
Pour que ce soit le cas, on emploie le mot-clé
suivi de la ou les colonnes sur lesquelles doit porter le tri.Si plusieurs colonnes sont spécifiées dans la consigne de tri, alors le tri s'effectuera d'abord sur les valeurs de la colonne la plus à gauche, puis selon les valeurs des colonnes données pour le tri de gauche à droite.
Notons par ailleurs que le tri s'effectue par défaut de manière ascendante. L'option
inversera le tri pour le critère concerné.Notre club de cuisine souhaite avoir la liste de ses adhérent·e·s constituée de leurs numéros, noms et prénoms mis en majuscules, triée par nom, puis par prénom.
Reprenons la table des adhérent·e·s :
idAdherent | nomAdherent | prenom | numero | rue | idVille | passe | telephone | |
1 | DURAND | Jacques | j.durand@orange.fr | 16b | rue brune | 1 | motdepass1 | 0601020304 |
2 | DUVAL | Paul | paul.d@sfr.fr | 135 | avenue rouge | 4 | motdepass2 | 0704030201 |
3 | DELORS | Sophie | sodelors@outlook.com | 22a | bd vert | 3 | motdepass3 | 0606060202 |
4 | VERGER | Jehan | jverger@aol.com | 4ter | impasse jaune | 5 | motdepass4 | 0601020102 |
5 | MONVILLE | Fleur | fleur1212@free.fr | 9 | sente aux loups | 2 | motdepass5 | 0707020201 |
6 | BRIARD | Paul | paul.briard27@hotmail.fr | 191 | rue violette | 4 | motdepass6 | 0612345678 |
7 | LÉGER | Marguerite | mag0506@perso.com | 17 | place noire | 3 | motdepass7 | 0687654321 |
8 | FLAMAND | Lise | flise@gmail.com | 329 | route bleue | 2 | motdepass8 | 0632323232 |
Voici la requête qui répond à l'objectif visé :
Le résultat suivant nous est restitué :
idAdherent | nomMaj | prenomMaj |
6 | BRIARD | PAUL |
3 | DELORS | SOPHIE |
1 | DURAND | JACQUES |
2 | DUVAL | PAUL |
8 | FLAMAND | LISE |
7 | LEGER | MARGUERITE |
5 | MONVILLE | FLEUR |
4 | VERGER | JEHAN |
Nous savons maintenant effectuer, dans une requête, des calculs sur les colonnes et sur les lignes d'une table ou transformer une colonne, ainsi que trier le résultat d'une requête. Voyons maintenant quand et comment effectuer des requêtes portant sur plusieurs tables.
Requêtes portant sur plusieurs tables
Requêtes portant sur plusieurs tables
Contexte d'une requête portant sur plusieurs tables
Contexte d'une requête portant sur plusieurs tables
Dans une base de données existent quasi systématiquement des associations. Celles-ci établissent un lien entre des entités. Ainsi, pour retrouver des informations relatives à une même entité, on peut être amené à récupérer celles-ci dans plusieurs tables par le biais de ces associations.
Pou rappel, les tables adherent et ville sont constituées ainsi :
idAdherent | nomAdherent | prenom | numero | rue | idVille | passe | telephone | |
1 | DURAND | Jacques | j.durand@orange.fr | 16b | rue brune | 1 | motdepass1 | 0601020304 |
2 | DUVAL | Paul | paul.d@sfr.fr | 135 | avenue rouge | 4 | motdepass2 | 0704030201 |
3 | DELORS | Sophie | sodelors@outlook.com | 22a | bd vert | 3 | motdepass3 | 0606060202 |
4 | VERGER | Jehan | jverger@aol.com | 4ter | impasse jaune | 5 | motdepass4 | 0601020102 |
5 | MONVILLE | Fleur | fleur1212@free.fr | 9 | sente aux loups | 2 | motdepass5 | 0707020201 |
6 | BRIARD | Paul | paul.briard27@hotmail.fr | 191 | rue violette | 4 | motdepass6 | 0612345678 |
7 | LÉGER | Marguerite | mag0506@perso.com | 17 | place noire | 3 | motdepass7 | 0687654321 |
8 | FLAMAND | Lise | flise@gmail.com | 329 | route bleue | 2 | motdepass8 | 0632323232 |
idVille | nomVille | codePostal |
1 | LE HAVRE | 76600 |
2 | CAEN | 14000 |
3 | NANTES | 44000 |
4 | RENNES | 35000 |
5 | QUIMPER | 29000 |
6 | VANNES | 56000 |
7 | SAINT-BRIEUC | 22000 |
8 | PONTIVY | 56300 |
9 | LOUDEAC | 22600 |
10 | QUIMPERLE | 29300 |
Nous ne sommes pas en mesure de connaître, dans notre table adherent, le nom de la ville où chaque adhérent·e habite. Nous connaissons néanmoins le numéro d'identification, soit idVille, de la ville où chacun habite. Grâce à ce numéro, nous pouvons retrouver le nom de celle-ci dans une autre table : la table ville.
Ainsi, si nous souhaitons recueillir la liste des adhérent·e·s de notre club de cuisine, constituée de leur numéro d'identification, nom, prénom et ville où ils résident, nous sommes appelés à effectuer des recherches dans deux tables : adherent et ville.
Dans ce contexte où nous effectuons une requête portant sur plusieurs tables, une ambiguïté concernant la désignation de leurs colonnes respectives peut se présenter.
- En effet, rien n'interdit de construire une base de données où un même nom de colonne peut figurer dans deux tables différentes.
Dans notre base de données, la table recette contient une colonne idRecette, tout comme la table etape.
Aussi, pour lever toute ambiguïté dans une requête qui porterait sur des tables ayant des colonnes nommées de la même manière, il est alors nécessaire de préfixer le nom de la colonne par celui de la table concernée.
- Finalement, on préfèrera, qu'il y ait ambiguïté ou non, préfixer tous les noms de colonnes du nom de la table à laquelle celles-ci appartiennent.
Dans notre exemple, ou désignera nos champs idRecette ainsi :
- recette.idRecette ;
- etape.idRecette ;
Et voici une requête utilisant un préfixe de nom de table :
À l'usage, on réalise que ce préfixe peut alourdir considérablement la rédaction de certaines requêtes, déjà complexes par ailleurs.
- On peut alors faire le choix de substituer le préfixe du nom de la table par un alias, plus court, qui sera précisé dans la commande SQL avec le mot-clé.
Notons que le recours à l'alias n'est pas obligatoire. ·
En affectant l’alias « re » pour notre table recette, la commande précédente est ainsi reformulée de façon plus compacte :
Apprenons maintenant à formuler des requêtes portant sur plusieurs tables. Il s'agit de l'opération de jointure que nous allons dès à présent détailler.
La jointure interne
La jointure interne
Dans le cas de la base de données de notre club de cuisine, pour obtenir la liste des adhérent·e·s constituée de leur numéro d'adhérent, leur nom, leur prénom et de la ville où ils résident, nous pourrions formaliser la requête suivante :
La logique de cette requête est tout à fait correcte. Le SGBD l’exécutera et donnera le résultat suivant :
idAdherent | nomAdherent | prenom | nomVille |
1 | Durand | Jacques | LE HAVRE |
2 | Duval | Paul | RENNES |
3 | Delors | Sophie | NANTES |
4 | Verger | Jehan | QUIMPER |
5 | Monville | Fleur | CAEN |
6 | Briard | Paul | RENNES |
7 | Leger | Marguerite | NANTES |
8 | Flamand | Lise | CAEN |
Cependant, il est nettement préférable d'avoir recours à un opérateur de jointure, nommé
, spécifique aux requêtes portant sur plusieurs tables.- Le SGBD traitera alors la requête de manière optimisée.
Jointure :
Une jointure consiste à combiner des données issues de deux ou plusieurs tables, sur la base d'un point commun.
La syntaxe requise pour effectuer une jointure est la suivante, dans le cadre de notre exemple :
Cette requête restituera le même résultat que précédemment, mais le SGBD aura optimisé les moyens de fournir ce résultat.
Notons par ailleurs qu'il est tout à fait possible de formaliser une requête ;SQL portant sur plus de deux tables.
Nous souhaitons avoir la liste des ingrédients de toutes les recettes, constituée de l'identifiant de la recette, du nom de la recette et du nom de l'ingrédient.
La table utilise nous permet de savoir quelle recette utilise quel ingrédient. En revanche, dans cette table, les recettes sont identifiées par la clé idRecette, ce qui ne nous donne pas leur nom. Idem pour la clé idIngredient qui ne nous permet pas de connaître le nom des ingrédients.
Mais on peut retrouver le nom chaque recette dans la table recette avec la clé idRecette. De même, on retrouve le nom de chaque ingrédient dans la table ingredient avec la clé idIngredient.
Voici nos tables :
idIngredient | idRecette | quantite | unite |
1 | 1 | 1 | jaune d’oeuf |
1 | 2 | 3 | oeufs entiers |
1 | 4 | 3 | oeufs entiers |
2 | 1 | 1 | cuillère |
3 | 1 | 1 | filet |
4 | 1 | 10 | cL |
5 | 2 | 1 | pincée |
5 | 3 | 1 | cuillère à café |
5 | 4 | 1 | pincee |
5 | 7 | 1 | pincée |
6 | 2 | 2 | tour de moulin |
6 | 7 | 2 | tours de moulin |
7 | 2 | 30 | g |
8 | 2 | 2 | cuillères à soupe |
8 | 6 | 1 | cuillère à soupe |
8 | 7 | 2 | cuillères à soupe |
9 | 3 | 150 | g |
9 | 4 | 180 | g |
9 | 7 | 100 | g |
10 | 3 | 75 | g |
10 | 4 | 180 | g |
10 | 7 | 20 | g |
11 | 4 | 180 | g |
12 | 3 | 20 | cL |
13 | 5 | 500 | g |
14 | 5 | 150 | g |
15 | 5 | 2 | pincées |
16 | 5 | 1 | pincée |
17 | 6 | 1 | poulet entier |
18 | 7 | 2 | branches |
19 | 7 | 1 | fruit entier |
20 | 7 | 4 | filets |
idRecette | nomRecette | niveau | duree | categorie | idAdherent |
1 | Mayonnaise | difficile | 15 | sauce | 7 |
2 | Omelette | facile | 5 | plat | 6 |
3 | Pâte brisée | moyen | 20 | autre | 6 |
4 | Quatre-quarts | facile | 10 | dessert | 4 |
5 | Purée de carottes | moyen | 15 | accompagnement | 2 |
6 | Poulet rôti | facile | 15 | plat | 2 |
7 | Sole meunière | difficile | 20 | plat | 7 |
idIngredient | nomIngredient | type |
1 | oeuf | viande |
2 | moutarde | condiment |
3 | vinaigre | condiment |
4 | huile | condiment |
5 | sel | condiment |
6 | poivre | condiment |
7 | gruyère râpé | crèmerie |
8 | huile d’olive | condiment |
9 | farine | épicerie |
10 | beurre | crèmerie |
11 | sucre | épicerie |
12 | lait | crèmerie |
13 | carotte | légume |
14 | crème fraîche | crémerie |
15 | cumin | condiment |
16 | muscade | condiment |
17 | poulet | viande |
18 | persil | condiment |
19 | citron | fruit |
20 | sole | viande |
Nous pourrions rédiger la commande SQL suivante :
Mais le SGBD n'optimisera pas ses traitements pour restituer le résultat. Utilisons à nouveau une jointure avec le mot-clé
:
Le résultat de ces deux commandes sera identique :
idRecette | nomRecette | nomIngredient |
1 | Mayonnaise | huile |
1 | Mayonnaise | moutarde |
1 | Mayonnaise | oeuf |
1 | Mayonnaise | vinaigre |
2 | Omelette | gruyère râpé |
2 | Omelette | huile d’olive |
2 | Omelette | oeuf |
2 | Omelette | poivre |
2 | Omelette | sel |
3 | Pâte brisée | beurre |
3 | Pâte brisée | farine |
3 | Pâte brisée | lait |
3 | Pâte brisée | sel |
4 | Quatre-quarts | beurre |
4 | Quatre-quarts | farine |
4 | Quatre-quarts | oeuf |
4 | Quatre-quarts | sel |
4 | Quatre-quarts | sucre |
5 | Purée de carottes | carotte |
5 | Purée de carottes | crème fraîche |
5 | Purée de carottes | cumin |
5 | Purée de carottes | muscade |
6 | Poulet rôti | huile d’olive |
6 | Poulet rôti | poulet |
7 | Sole meunière | beurre |
7 | Sole meunière | citron |
7 | Sole meunière | farine |
7 | Sole meunière | huile d’olive |
7 | Sole meunière | persil |
7 | Sole meunière | poivre |
7 | Sole meunière | sel |
7 | Sole meunière | sole |
La jointure externe
La jointure externe
La jointure externe permet d’effectuer une jointure en incluant les lignes dont la clé étrangère qui fait le lien entre deux tables n’est pas renseignée. Sachant que deux tables sont considérées dans cette jointure, il faut préciser laquelle des deux servira de référence.
Ainsi, toutes les lignes de la table qui servira de référence seront représentées dans la table résultat. L’attribut ou les attributs récupérés via la clé étrangère seront renseignés avec la valeur trouvée dans la seconde table, ou renseignée à « NULL » lorsque la clé étrangère n’est pas renseignée dans la première table.
Il faudra employer pour cela la clause
.On souhaite avoir la liste des adhérent·e·s constituée de leur numéro d’identification, leur nom, leur prénom, l’identifiant et le nom de chaque recette rédigée par un adhérent donné.
On passera la commande suivante :
Pour rappel, les tables concernées sont constituées comme suit :
idRecette | nomRecette | niveau | duree | categorie | idAdherent |
1 | Mayonnaise | difficile | 15 | sauce | 7 |
2 | Omelette | facile | 5 | plat | 6 |
3 | Pâte brisée | moyen | 20 | autre | 6 |
4 | Quatre-quarts | facile | 10 | dessert | 4 |
5 | Purée de carottes | moyen | 15 | accompagnement | 2 |
6 | Poulet rôti | facile | 15 | plat | 2 |
7 | Sole meunière | difficile | 20 | plat | 7 |
idAdherent | nomAdherent | prenom | numero | rue | idVille | passe | telephone | |
1 | DURAND | Jacques | j.durand@orange.fr | 16b | rue brune | 1 | motdepass1 | 0601020304 |
2 | DUVAL | Paul | paul.d@sfr.fr | 135 | avenue rouge | 4 | motdepass2 | 0704030201 |
3 | DELORS | Sophie | sodelors@outlook.com | 22a | bd vert | 3 | motdepass3 | 0606060202 |
4 | VERGER | Jehan | jverger@aol.com | 4ter | impasse jaune | 5 | motdepass4 | 0601020102 |
5 | MONVILLE | Fleur | fleur1212@free.fr | 9 | sente aux loups | 2 | motdepass5 | 0707020201 |
6 | BRIARD | Paul | paul.briard27@hotmail.fr | 191 | rue violette | 4 | motdepass6 | 0612345678 |
7 | LÉGER | Marguerite | mag0506@perso.com | 17 | place noire | 3 | motdepass7 | 0687654321 |
8 | FLAMAND | Lise | flise@gmail.com | 329 | route bleue | 2 | motdepass8 | 0632323232 |
On obtient :
idAdherent | nomAdherent | prenom | idRecette | nomRecette |
2 | Duval | Paul | 6 | Poulet rôti |
2 | Duval | Paul | 5 | Purée de carottes |
4 | Verger | Jehan | 4 | Quatre-quarts |
6 | Briard | Paul | 2 | Omelette |
6 | Briard | Paul | 3 | Pâte brisée |
7 | Leger | Marguerite | 1 | Mayonnaise |
7 | Leger | Marguerite | 7 | Sole meunière |
Mais nous souhaiterions que cette liste d’adhérent·e·s n’exclue pas ceux qui n’ont rédigé aucune recette. Pour cela, il faut faire appel à une jointure externe, en prenant adherent comme table de référence.
La commande SQL qui correspond se formalise ainsi :
Ce qui veut dire que la commande qui suit est identique à la précédente :
Et le résultat obtenu est le suivant :
idAdherent | nomAdherent | prenom | idRecette | nomRecette |
1 | Durand | Jacques | NULL | NULL |
2 | Duval | Paul | 6 | Poulet rôti |
2 | Duval | Paul | 5 | Purée de carottes |
3 | Delors | Sophie | NULL | NULL |
4 | Verger | Jehan | 4 | Quatre-quarts |
5 | Monville | Fleur | NULL | NULL |
6 | Briard | Paul | 2 | Omelette |
6 | Briard | Paul | 3 | Pâte brisée |
7 | Leger | Marguerite | 1 | Mayonnaise |
7 | Leger | Marguerite | 7 | Sole meunière |
8 | Flamand | Lise | NULL | NULL |
Prenons maintenant la table recette en référence en inscrivant la commande :
On obtient alors :
idAdherent | nomAdherent | prenom | idRecette | nomRecette |
2 | Duval | Paul | 6 | Poulet rôti |
2 | Duval | Paul | 5 | Purée de carottes |
4 | Verger | Jehan | 4 | Quatre-quarts |
6 | Briard | Paul | 2 | Omelette |
6 | Briard | Paul | 3 | Pâte brisée |
7 | Leger | Marguerite | 1 | Mayonnaise |
7 | Leger | Marguerite | 7 | Sole meunière |
Comme voulu, toutes les lignes de la table recette sont représentées dans la table résultat. Notons que l’on n’observe aucune colonne nulle (« NULL ») parmi les lignes de la table résultat. Cette particularité est due au fait que toute recette est forcément rédigée par un·e adhérent·e. L’inverse n’étant pas vrai, on l’a vu précédemment : tout adhérent n’a pas forcément rédigé une recette.
Pour terminer, on peut tenter de combiner différentes clauses. Si nous souhaitons par exemple connaître tous les adhérent·e·s qui n’ont pas proposé de recette, il suffira de passer la commande SQL suivante :
Ce qui donnera le résultat escompté, à savoir :
idAdherent | nomAdherent | prenom | idRecette | nomRecette |
1 | Durand | Jacques | NULL | NULL |
3 | Delors | Sophie | NULL | NULL |
5 | Monville | Fleur | NULL | NULL |
8 | Flamand | Lise | NULL | NULL |
Conclusion :
Nous achevons ainsi ce cours donnant des notions complémentaires sur le langage SQL. Vous savez dorénavant rédiger des requêtes élaborées, faisant appel à des mécanismes de calcul, de regroupement, de transformation, de tri ou encore de jointure.