Aller au contenu

Le langage SQL et les requêtes

Terminale · NSI · Bases de données

Bases de données

Interroger une base : SELECT, WHERE, ORDER BY

SQL (Structured Query Language) est le langage universel des bases de données relationnelles. Sa particularité : il est déclaratif. Tu décris ce que tu veux obtenir, pas comment l'obtenir — c'est le SGBD qui choisit la stratégie d'exécution la plus efficace. Une requête SQL bien écrite remplace souvent cinquante lignes de Python.

La base de référence. On reprend la médiathèque, avec un contenu précis à garder sous les yeux :
Auteur(id_auteur, nom, prenom, nationalite) :
1 · Orwell · George · britannique — 2 · Camus · Albert · française — 3 · Hugo · Victor · française — 4 · Christie · Agatha · britannique

Livre(id_livre, titre, annee, id_auteur) :
10 · 1984 · 1949 · 1 — 11 · La Ferme des animaux · 1945 · 1 — 12 · L'Étranger · 1942 · 2
13 · La Peste · 1947 · 2 — 14 · Les Misérables · 1862 · 3 — 15 · Le Crime de l'Orient-Express · 1934 · 4

ClauseRôleExemple sur la médiathèque
SELECTChoisit les colonnes du résultat (projection)SELECT titre, annee FROM Livre
FROMIndique la ou les tables interrogéesFROM Livre
WHEREFiltre les lignes selon une condition (sélection)WHERE annee > 1940
ORDER BYTrie le résultat, ASC par défaut, DESC pour décroissantORDER BY annee DESC
DISTINCTSupprime les doublons du résultatSELECT DISTINCT nationalite FROM Auteur
LIMITNe garde que les n premières lignesORDER BY annee DESC LIMIT 1

Modifier les données

Trois instructions modifient le contenu des tables. Elles s'écrivent avec des syntaxes bien distinctes qu'il faut connaître par cœur :
INSERT INTO Livre (id_livre, titre, annee, id_auteur) VALUES (16, 'Le Meilleur des mondes', 1932, 5) ;
UPDATE Livre SET annee = 1949 WHERE id_livre = 10 ;
DELETE FROM Livre WHERE id_livre = 15 ;

Remarque bien qu'on écrit INSERT INTO et DELETE FROM, mais UPDATE sans mot de liaison. Et il n'y a jamais de SET dans un INSERT.

Bases de données

Jointures, agrégats et regroupements

Le modèle relationnel éclate volontairement l'information en plusieurs tables pour éviter la redondance. La jointure est l'opération qui les rassemble au moment de la requête : elle permet d'afficher le titre d'un livre et le nom de son auteur, alors que ces deux données vivent dans des tables différentes.

Les fonctions d'agrégation. Une fonction d'agrégation résume un ensemble de lignes en une seule valeur. Elles s'écrivent dans la clause SELECT et s'appliquent, par défaut, à toutes les lignes retenues par le WHERE.

FonctionCe qu'elle calculeExempleRésultat sur la médiathèque
COUNT(*)Le nombre de lignesSELECT COUNT(*) FROM Livre6
MINLa plus petite valeurSELECT MIN(annee) FROM Livre1862
MAXLa plus grande valeurSELECT MAX(annee) FROM Livre1949
SUMLa somme des valeursSELECT SUM(annee) FROM Livre(peu de sens ici, mais valide)
AVGLa moyenne des valeursSELECT AVG(annee) FROM Livrela moyenne des 6 années

GROUP BY et HAVING. La clause GROUP BY découpe les lignes en paquets partageant une même valeur, et applique la fonction d'agrégation à chaque paquet séparément. La clause HAVING filtre ensuite ces paquets.

Exercices corrigés

  1. Quelle requête affiche les titres et les années de tous les livres de la table Livre ?

    • A.SELECT Livre FROM titre, annee ;
    • B.GET titre, annee FROM Livre ;
    • C.SELECT titre, annee FROM Livre ;Bonne réponse
    • D.SELECT titre, annee IN Livre ;

    Réponse : C — SELECT titre, annee FROM Livre ;

    La structure de base est immuable : SELECT suivi des colonnes voulues, puis FROM suivi de la table. La première option inverse les deux rôles, en demandant la colonne Livre dans une table titre. Le mot-clé GET n'existe pas en SQL, et la table s'introduit par FROM, jamais par IN. Retiens la formule : SELECT dit QUOI afficher, FROM dit OÙ chercher.

  2. Quelle clause permet de trier le résultat d'une requête du plus récent au plus ancien selon la colonne annee ?

    • A.SORT BY annee DESC
    • B.ORDER BY annee ASC
    • C.GROUP BY annee DESC
    • D.ORDER BY annee DESCBonne réponse

    Réponse : D — ORDER BY annee DESC

    Le tri s'écrit ORDER BY, et non SORT BY qui n'existe pas en SQL. Reste à choisir le sens : ASC (ascendant) trie du plus petit au plus grand, donc du plus ancien au plus récent, tandis que DESC (descendant) fait l'inverse — c'est bien ce qu'on veut ici. À noter : ASC est le tri par défaut, on peut donc l'omettre, mais DESC doit toujours être écrit explicitement. Quant à GROUP BY, il ne trie rien : il regroupe.

  3. Que fait exactement la requête DELETE FROM Livre ; écrite sans clause WHERE ?

    • A.Elle supprime toutes les lignes de la table Livre, qui reste vide mais existanteBonne réponse
    • B.Elle supprime la table Livre ainsi que sa structure
    • C.Elle est refusée par le SGBD, un DELETE exigeant toujours une condition
    • D.Elle ne supprime que la première ligne de la table

    Réponse : A — Elle supprime toutes les lignes de la table Livre, qui reste vide mais existante

    Sans WHERE, la condition est absente, donc toutes les lignes sont concernées : la table est intégralement vidée. Sa structure, en revanche, demeure — les colonnes, les types, les contraintes sont toujours là, prêtes à recevoir de nouvelles données. C'est ce qui distingue DELETE de DROP TABLE Livre, qui supprimerait la table elle-même. Et non, le SGBD ne te protège pas : il exécute sans broncher. D'où le réflexe à prendre : écrire la clause WHERE avant même de taper le reste de la requête.

  4. La table Livre contient les années 1949, 1945, 1942, 1947, 1862 et 1934. Combien de lignes renvoie la requête SELECT titre FROM Livre WHERE annee > 1940 ; ?

    • A.6
    • B.4Bonne réponse
    • C.2
    • D.5

    Réponse : B — 4

    On teste la condition sur chaque ligne, une par une : 1949 > 1940 oui, 1945 oui, 1942 oui, 1947 oui, 1862 non, 1934 non. Quatre lignes passent le filtre. Répondre 6 reviendrait à ignorer le WHERE, et répondre 2 à compter les lignes rejetées au lieu des lignes retenues. Note bien que la comparaison est stricte : une année valant exactement 1940 aurait été exclue.

  5. Quelle requête corrige l'année du livre d'identifiant 14 pour la fixer à 1862 ?

    • A.UPDATE Livre SET annee = 1862 WHERE id_livre = 14 ;Bonne réponse
    • B.UPDATE Livre WHERE id_livre = 14 SET annee = 1862 ;
    • C.MODIFY Livre SET annee = 1862 WHERE id_livre = 14 ;
    • D.UPDATE Livre VALUES annee = 1862 WHERE id_livre = 14 ;

    Réponse : A — UPDATE Livre SET annee = 1862 WHERE id_livre = 14 ;

    La syntaxe est UPDATE (nom de la table) SET (colonne = nouvelle valeur) WHERE (condition), toujours dans cet ordre : on dit d'abord ce qu'on change, ensuite sur quelles lignes. La deuxième option intervertit SET et WHERE, ce que le SGBD refuse. MODIFY n'existe pas en SQL, et VALUES appartient exclusivement à INSERT. Retiens surtout le rôle vital du WHERE ici : sans lui, les six livres se verraient attribuer l'année 1862.

  6. Combien de lignes renvoie SELECT titre FROM Livre WHERE annee > 1940 AND id_auteur = 1 ; sachant que l'auteur 1 a écrit 1984 (1949) et La Ferme des animaux (1945), et qu'aucun autre livre ne lui appartient ?

    • A.2Bonne réponse
    • B.4
    • C.6
    • D.0

    Réponse : A — 2

    L'opérateur AND exige que les DEUX conditions soient vraies simultanément. Seuls les livres de l'auteur 1 sont candidats, soit 1984 et La Ferme des animaux, et il faut ensuite vérifier l'année : 1949 > 1940 oui, 1945 > 1940 oui. Les deux passent, la réponse est donc 2. Répondre 4 correspondrait à ne garder que la première condition, et 6 à ignorer les deux. Souviens-toi qu'un AND ne peut que réduire le nombre de lignes, alors qu'un OR ne peut que l'augmenter.

  7. On veut afficher les auteurs ayant écrit au moins deux livres. Quelle clause doit porter la condition COUNT(*) >= 2 ?

    • A.WHERE, placée avant le GROUP BY
    • B.ORDER BY, placée après le HAVING
    • C.SELECT, en ajoutant un DISTINCT
    • D.HAVING, placée après le GROUP BYBonne réponse

    Réponse : D — HAVING, placée après le GROUP BY

    La condition porte sur un résultat d'agrégation, donc sur un groupe déjà constitué : il faut HAVING, qui s'applique après le GROUP BY. Le WHERE, lui, s'exécute avant le regroupement, à un moment où les paquets n'existent pas encore et où COUNT(*) n'a donc aucun sens : écrire WHERE COUNT(*) >= 2 provoque une erreur de syntaxe. Retiens la règle : WHERE filtre les lignes, HAVING filtre les groupes. La requête complète s'écrit SELECT id_auteur, COUNT(*) FROM Livre GROUP BY id_auteur HAVING COUNT(*) >= 2 ;

  8. Dans la table Emprunt, la colonne date_retour vaut NULL tant que le livre n'a pas été rendu. La table compte 10 lignes, dont 3 avec date_retour à NULL. Que renvoient respectivement COUNT(*) et COUNT(date_retour) ?

    • A.10 et 3
    • B.7 et 7
    • C.10 et 7Bonne réponse
    • D.10 et 10

    Réponse : C — 10 et 7

    COUNT(*) compte toutes les lignes de la table sans se soucier de leur contenu : il renvoie 10. COUNT(date_retour) ne compte en revanche que les lignes où cette colonne a une valeur renseignée, en ignorant les NULL : il renvoie donc 10 − 3 = 7. Cette différence est très utile en pratique, puisque l'écart entre les deux donne directement le nombre de livres non encore rendus. Rappelle-toi que NULL ne signifie pas zéro mais « valeur inconnue », et que les fonctions d'agrégation l'écartent systématiquement.

  9. Sur une table Livre où l'auteur 1 a 2 livres, l'auteur 2 en a 2, l'auteur 3 en a 1 et l'auteur 4 en a 1, combien de lignes renvoie SELECT id_auteur, COUNT(*) FROM Livre GROUP BY id_auteur HAVING COUNT(*) >= 2 ; ?

    • A.4
    • B.2Bonne réponse
    • C.6
    • D.1

    Réponse : B — 2

    Procédons dans l'ordre d'exécution réel. Le GROUP BY forme d'abord quatre paquets, un par auteur, avec les effectifs 2, 2, 1 et 1. Le HAVING filtre ensuite ces paquets en ne gardant que ceux dont l'effectif atteint 2 : les auteurs 1 et 2 passent, les auteurs 3 et 4 sont éliminés. Il reste donc 2 lignes. Répondre 4 revient à oublier le HAVING, et répondre 6 à compter les livres au lieu des groupes — c'est le contresens le plus fréquent : après un GROUP BY, chaque ligne du résultat représente un groupe entier, pas un enregistrement de la table.

  10. Un élève écrit SELECT titre, nom FROM Livre, Auteur ; en oubliant toute condition de rapprochement. La table Livre compte 6 lignes et la table Auteur 4. Que produit cette requête ?

    • A.6 lignes, chaque livre étant associé à son unique auteur comme le souhaitait l'élève au départ
    • B.4 lignes seulement, une par auteur, les livres n'apparaissant nulle part dans le résultat final
    • C.Une erreur de syntaxe bloquante, le SGBD refusant purement et simplement d'exécuter cette requête mal écrite
    • D.24 lignes : chaque livre est associé à chacun des 4 auteurs, y compris ceux qui ne l'ont pas écritBonne réponse

    Réponse : D — 24 lignes : chaque livre est associé à chacun des 4 auteurs, y compris ceux qui ne l'ont pas écrit

    Citer deux tables sans indiquer comment les rapprocher revient à demander toutes les combinaisons possibles : c'est le produit cartésien, qui compte 6 × 4 = 24 lignes. Chaque livre s'y retrouve apparié aux quatre auteurs, ce qui attribue par exemple 1984 à Victor Hugo. Le piège est redoutable parce que la requête est parfaitement valide sur le plan syntaxique : le SGBD ne signale aucune erreur et renvoie tranquillement des données fausses. C'est justement le rôle de la condition ON (ou d'un WHERE Livre.id_auteur = Auteur.id_auteur) : elle ne conserve, parmi ces 24 combinaisons, que les 6 où la clé étrangère correspond bien à la clé primaire.

  11. À quoi sert la clause WHERE dans une requête SQL ?

    • A.À filtrer les lignes en ne conservant que celles qui vérifient une conditionBonne réponse
    • B.À choisir les colonnes à afficher
    • C.À trier le résultat par ordre croissant
    • D.À indiquer dans quelle table chercher les données

    Réponse : A — À filtrer les lignes en ne conservant que celles qui vérifient une condition

    WHERE agit sur les lignes : il ne garde que celles qui satisfont la condition, par exemple WHERE annee > 1940. C'est ce qu'on appelle une sélection. Ne le confonds pas avec SELECT, qui agit sur les colonnes (une projection), ni avec ORDER BY, qui trie, ni avec FROM, qui désigne la table. Une bonne façon de retenir : SELECT découpe verticalement, WHERE découpe horizontalement.

  12. Quelle est la syntaxe correcte pour ajouter un nouvel enregistrement dans la table Auteur ?

    • A.ADD INTO Auteur VALUES (5, 'Zola', 'Émile', 'française') ;
    • B.INSERT INTO Auteur (id_auteur, nom, prenom, nationalite) VALUES (5, 'Zola', 'Émile', 'française') ;Bonne réponse
    • C.INSERT INTO Auteur SET nom = 'Zola' ;
    • D.UPDATE Auteur VALUES (5, 'Zola', 'Émile', 'française') ;

    Réponse : B — INSERT INTO Auteur (id_auteur, nom, prenom, nationalite) VALUES (5, 'Zola', 'Émile', 'française') ;

    L'ajout d'une ligne s'écrit INSERT INTO, suivi du nom de la table, de la liste des colonnes, puis du mot-clé VALUES et des valeurs correspondantes entre parenthèses. Les trois autres options mélangent les syntaxes : ADD INTO n'existe pas ; SET appartient à UPDATE et jamais à INSERT ; et UPDATE sert à modifier une ligne existante, pas à en créer une. Note aussi que les chaînes de caractères sont entourées d'apostrophes, contrairement aux nombres.

S'entraîner sur ce chapitre

Ce chapitre compte 37 exercices corrigés dans l'application, avec le suivi de ta progression.

Commencer les exercices