\documentclass[10pt,aspectratio=169]{beamer}

% --- Thème ---
\usetheme[language=french]{Celestia}

% Avec [allowframebreaks] sur les frames de questions, Beamer ajoute
% par défaut « (1) », « (2) », « (3) »... sur chaque sous-slide. On
% supprime entièrement cette annotation : un template vide pour
% « frametitle continuation ». L'enseignant identifie visuellement la
% continuation par le contenu de la slide. (Les variantes [from second]
% et [roman] interagissent mal avec un titre contenant \textemdash{}
% sous Celestia : elles déclenchent une erreur « Missing $ inserted ».)
\setbeamertemplate{frametitle continuation}{}

\subject{Numérique et sciences informatiques}
\title{Bases de données et SQL}
\subtitle{QCM}
\author{Terminale}
\date{\today}

\begin{document}

\begin{frame}
    \titlepage
\end{frame}

% Q1 - Réponse en D
\begin{frame}[fragile]{Question 1 \textemdash{} Définition d'un SGBD}
    Que désigne le sigle SGBD ?\medskip
    \begin{itemize}
        \item[A.] Stockage Garanti des Bases Distribuées
        \item[B.] Système de Génération Binaire de Données
        \item[C.] Standard Général des Bibliothèques de Données
        \item[\alert<2>{D.}] \alert<2>{Système de Gestion de Base de Données}
    \end{itemize}
\end{frame}

% Q2 - Réponse en B
\begin{frame}[fragile]{Question 2 \textemdash{} Vocabulaire du modèle relationnel}
    Dans le modèle relationnel, comment appelle-t-on \textbf{une ligne}
d'une table ?\medskip
    \begin{itemize}
        \item[A.] Un attribut
        \item[\alert<2>{B.}] \alert<2>{Un n-uplet (ou enregistrement)}
        \item[C.] Une clé
        \item[D.] Un domaine
    \end{itemize}
\end{frame}

% Q3 - Réponse en A
\begin{frame}[fragile]{Question 3 \textemdash{} Clé primaire}
    Quelle est la propriété fondamentale d'une \textbf{clé primaire} ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Elle identifie de manière unique chaque ligne de la table}
        \item[B.] Elle doit être un nombre entier
        \item[C.] Elle peut prendre la valeur \texttt{NULL}
        \item[D.] Elle doit toujours être une seule colonne
    \end{itemize}
\end{frame}

% Q4 - Réponse en A
\begin{frame}[fragile]{Question 4 \textemdash{} Clé étrangère}
    Que représente une \textbf{clé étrangère} dans une table ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Un attribut qui référence la clé primaire d'une autre table}
        \item[B.] Une clé qui ne peut pas être modifiée
        \item[C.] Une clé importée d'un autre fichier
        \item[D.] Un attribut crypté pour la sécurité
    \end{itemize}
\end{frame}

% Q5 - Réponse en C
\begin{frame}[fragile]{Question 5 \textemdash{} Syntaxe de base de SELECT}
    Quelle est la syntaxe SQL pour récupérer \textbf{toutes} les
colonnes de la table \texttt{eleves} ?\medskip
    \begin{itemize}
        \item[A.] \texttt{SELECT eleves}
        \item[B.] \texttt{GET ALL FROM eleves}
        \item[\alert<2>{C.}] \alert<2>{\texttt{SELECT * FROM eleves}}
        \item[D.] \texttt{READ eleves}
    \end{itemize}
\end{frame}

% Q6 - Réponse en C
\begin{frame}[fragile]{Question 6 \textemdash{} Filtrage avec WHERE}
    Pour ne sélectionner que les élèves majeurs de la table
\texttt{eleves}, quelle requête utiliser ?\medskip
    \begin{itemize}
        \item[A.] \texttt{FILTER eleves WHERE age >= 18}
        \item[B.] \texttt{SELECT * FROM eleves CONDITION age >= 18}
        \item[\alert<2>{C.}] \alert<2>{\texttt{SELECT * FROM eleves WHERE age >= 18}}
        \item[D.] \texttt{SELECT * FROM eleves IF age >= 18}
    \end{itemize}
\end{frame}

% Q7 - Réponse en B
\begin{frame}[fragile]{Question 7 \textemdash{} Tri avec ORDER BY}
    Pour afficher les élèves par ordre alphabétique de leur
nom, on utilise :\medskip
    \begin{itemize}
        \item[A.] \texttt{SELECT * FROM eleves ARRANGE BY nom}
        \item[\alert<2>{B.}] \alert<2>{\texttt{SELECT * FROM eleves ORDER BY nom}}
        \item[C.] \texttt{SELECT * FROM eleves SORTED nom}
        \item[D.] \texttt{SELECT * FROM eleves SORT BY nom}
    \end{itemize}
\end{frame}

% Q8 - Réponse en B
\begin{frame}[fragile]{Question 8 \textemdash{} Contraintes d'intégrité}
    Qu'est-ce qu'une \textbf{contrainte d'intégrité} dans une base de
données relationnelle ?\medskip
    \begin{itemize}
        \item[A.] Un mot de passe pour accéder à une table
        \item[\alert<2>{B.}] \alert<2>{Une règle qui restreint les valeurs admissibles dans la base, vérifiée par le SGBD}
        \item[C.] Une copie de sauvegarde automatique
        \item[D.] Un index pour accélérer les requêtes
    \end{itemize}
\end{frame}

% Q9 - Réponse en A
\begin{frame}[fragile]{Question 9 \textemdash{} Insertion d'une ligne}
    Quelle commande SQL ajoute une ligne dans une table ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{INSERT INTO eleves VALUES ('Alice', 17)}}
        \item[B.] \texttt{CREATE INTO eleves VALUES ('Alice', 17)}
        \item[C.] \texttt{PUT INTO eleves VALUES ('Alice', 17)}
        \item[D.] \texttt{ADD INTO eleves VALUES ('Alice', 17)}
    \end{itemize}
\end{frame}

% Q10 - Réponse en B
\begin{frame}[fragile]{Question 10 \textemdash{} Valeurs atomiques}
    Dans une base relationnelle correctement conçue, on
attend que chaque attribut contienne une valeur
\textbf{atomique}. Que signifie cette propriété ?\medskip
    \begin{itemize}
        \item[A.] La valeur doit être un entier
        \item[\alert<2>{B.}] \alert<2>{La valeur n'est pas décomposable en plusieurs informations distinctes (par exemple, on ne stocke pas plusieurs numéros de téléphone dans une même cellule)}
        \item[C.] La valeur ne peut jamais être modifiée
        \item[D.] La valeur ne peut pas être nulle
    \end{itemize}
\end{frame}

% Q11 - Réponse en A
\begin{frame}[fragile]{Question 11 \textemdash{} Jointure entre deux tables}
    Pour combiner les tables \texttt{commandes} et \texttt{clients} en
reliant \texttt{commandes.client\_id} à \texttt{clients.id}, quelle
syntaxe utiliser ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{SELECT * FROM commandes JOIN clients ON commandes.client\_id = clients.id}}
        \item[B.] \texttt{SELECT * FROM commandes, clients}
        \item[C.] \texttt{SELECT * FROM commandes WITH clients}
        \item[D.] \texttt{SELECT * FROM commandes UNION clients}
    \end{itemize}
\end{frame}

% Q12 - Réponse en D
\begin{frame}[fragile]{Question 12 \textemdash{} Fonctions d'agrégation}
    Pour calculer la \textbf{moyenne des âges} des élèves, quelle
requête utiliser ?\medskip
    \begin{itemize}
        \item[A.] \texttt{SELECT MOYENNE(age) FROM eleves}
        \item[B.] \texttt{SELECT (age) FROM eleves AVERAGE}
        \item[C.] \texttt{SELECT MEAN(age) FROM eleves}
        \item[\alert<2>{D.}] \alert<2>{\texttt{SELECT AVG(age) FROM eleves}}
    \end{itemize}
\end{frame}

% Q13 - Réponse en B
\begin{frame}[fragile]{Question 13 \textemdash{} Combiner WHERE et ORDER BY}
    Quelle requête renvoie les noms des élèves majeurs,
classés par âge \textbf{décroissant} ?\medskip
    \begin{itemize}
        \item[A.] \texttt{SELECT nom FROM eleves ORDER BY age DESC WHERE age >= 18}
        \item[\alert<2>{B.}] \alert<2>{\texttt{SELECT nom FROM eleves WHERE age >= 18 ORDER BY age DESC}}
        \item[C.] \texttt{SELECT nom FROM eleves WHERE age >= 18 ORDER BY age}
        \item[D.] \texttt{SELECT nom FROM eleves WHERE age >= 18 SORT age DESC}
    \end{itemize}
\end{frame}

% Q14 - Réponse en B
\begin{frame}[fragile]{Question 14 \textemdash{} Modification d'une ligne}
    Pour augmenter de $1$ point la note de l'élève d'identifiant
$42$, quelle requête utiliser ?\medskip
    \begin{itemize}
        \item[A.] \texttt{MODIFY eleves SET note = note + 1 WHERE id = 42}
        \item[\alert<2>{B.}] \alert<2>{\texttt{UPDATE eleves SET note = note + 1 WHERE id = 42}}
        \item[C.] \texttt{UPDATE eleves WHERE id = 42 SET note = note + 1}
        \item[D.] \texttt{CHANGE eleves SET note = note + 1 WHERE id = 42}
    \end{itemize}
\end{frame}

% Q15 - Réponse en A
\begin{frame}[fragile]{Question 15 \textemdash{} Suppression de doublons}
    Pour obtenir la liste des \textbf{classes différentes} présentes
dans la table \texttt{eleves} (sans doublons), quelle requête
utiliser ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{SELECT DISTINCT classe FROM eleves}}
        \item[B.] \texttt{SELECT classe DISTINCT FROM eleves}
        \item[C.] \texttt{SELECT UNIQUE classe FROM eleves}
        \item[D.] \texttt{SELECT classe FROM eleves}
    \end{itemize}
\end{frame}

% Q16 - Réponse en D
\begin{frame}[fragile]{Question 16 \textemdash{} Représenter une association multiple}
    On souhaite représenter le fait qu'un élève peut
suivre \textbf{plusieurs cours} et qu'un cours peut
accueillir \textbf{plusieurs élèves}. Quel schéma
relationnel adopter ?\medskip
    \begin{itemize}
        \item[A.] Deux tables avec une duplication des cours dans chaque ligne d'élève
        \item[B.] Une seule table \texttt{eleves} avec autant de colonnes \texttt{cours\_1}, \texttt{cours\_2}, \texttt{cours\_3} qu'il y a de cours possibles
        \item[C.] Une seule table contenant \texttt{eleve} et tous ses cours dans une même cellule
        \item[\alert<2>{D.}] \alert<2>{Trois tables \texttt{eleves(id, nom)}, \texttt{cours(id, intitule)} et \texttt{inscriptions(eleve\_id, cours\_id)} reliées par des clés étrangères}
    \end{itemize}
\end{frame}

% Q17 - Réponse en B
\begin{frame}[fragile]{Question 17 \textemdash{} Recherche avec LIKE}
    Pour trouver tous les élèves dont le nom commence par "Du",
quelle requête utiliser ?\medskip
    \begin{itemize}
        \item[A.] \texttt{WHERE nom STARTS 'Du'}
        \item[\alert<2>{B.}] \alert<2>{\texttt{WHERE nom LIKE 'Du\%'}}
        \item[C.] \texttt{WHERE nom = 'Du'}
        \item[D.] \texttt{WHERE nom CONTAINS 'Du'}
    \end{itemize}
\end{frame}

% Q18 - Réponse en A
\begin{frame}[fragile]{Question 18 \textemdash{} Suppression d'une ligne}
    Que fait la requête \texttt{DELETE FROM eleves;} ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Elle supprime toutes les lignes de la table \texttt{eleves}}
        \item[B.] Elle supprime la table entière (structure et contenu)
        \item[C.] Elle ne fait rien (manque de \texttt{WHERE})
        \item[D.] Elle lève une erreur SQL
    \end{itemize}
\end{frame}

% Q19 - Réponse en C
\begin{frame}[fragile]{Question 19 \textemdash{} Services rendus par un SGBD}
    Lequel des éléments suivants n'est \textbf{pas} un
service rendu par un système de gestion de bases de
données ?\medskip
    \begin{itemize}
        \item[A.] La gestion des accès concurrents par plusieurs utilisateurs ou programmes
        \item[B.] La persistance des données (les données survivent à l'arrêt du programme)
        \item[\alert<2>{C.}] \alert<2>{La compilation du code source d'un programme Python}
        \item[D.] La sécurisation des accès (authentification, droits par utilisateur)
    \end{itemize}
\end{frame}

% Q20 - Réponse en B
\begin{frame}[fragile]{Question 20 \textemdash{} Intégrité référentielle}
    Quelle situation viole l'\textbf{intégrité référentielle} ?\medskip
    \begin{itemize}
        \item[A.] Avoir deux clients avec le même nom
        \item[\alert<2>{B.}] \alert<2>{Insérer une commande avec un \texttt{client\_id} qui n'existe pas dans la table \texttt{clients}}
        \item[C.] Insérer une commande sans préciser la quantité
        \item[D.] Trier les commandes par date
    \end{itemize}
\end{frame}

% Q21 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 21 \textemdash{} Sous-requête}
    Que renvoie cette requête ?

\begin{lstlisting}
SELECT nom FROM eleves
WHERE moyenne > (SELECT AVG(moyenne) FROM eleves);
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] Les moyennes des élèves au-dessus de zéro
        \item[B.] Une erreur (sous-requête non autorisée)
        \item[C.] La moyenne des moyennes des élèves
        \item[D.] Les noms des élèves dont la moyenne est strictement supérieure à la moyenne de la classe
    \end{itemize}
\end{frame}

% Q21 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 21 \textemdash{} Sous-requête}
    Que renvoie cette requête ?

\begin{lstlisting}
SELECT nom FROM eleves
WHERE moyenne > (SELECT AVG(moyenne) FROM eleves);
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] Les moyennes des élèves au-dessus de zéro
        \item[B.] Une erreur (sous-requête non autorisée)
        \item[C.] La moyenne des moyennes des élèves
        \item[\alert{D.}] \alert{Les noms des élèves dont la moyenne est strictement supérieure à la moyenne de la classe}
    \end{itemize}
\end{frame}

% Q22 - Réponse en B
\begin{frame}[fragile]{Question 22 \textemdash{} Détection d'une redondance}
    Une table \texttt{commandes(id, client\_id, nom\_client, prenom\_client, produit, prix)}
pose un problème classique de schéma. Lequel ?\medskip
    \begin{itemize}
        \item[A.] La clé primaire est mal choisie
        \item[\alert<2>{B.}] \alert<2>{Les informations du client (nom, prénom) sont dupliquées à chaque commande, ce qui crée des incohérences potentielles si les noms sont mal mis à jour}
        \item[C.] Le prix devrait être stocké séparément
        \item[D.] La table contient trop de colonnes
    \end{itemize}
\end{frame}

% Q23 - Réponse en A
\begin{frame}[fragile]{Question 23 \textemdash{} Différence entre INNER et LEFT JOIN}
    Quelle est la différence entre \texttt{INNER JOIN} et \texttt{LEFT JOIN} ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{\texttt{INNER JOIN} ne garde que les paires appariées ; \texttt{LEFT JOIN} garde toutes les lignes de la table de gauche, complétées par \texttt{NULL} à droite si aucune correspondance}
        \item[B.] Aucune, ce sont des synonymes
        \item[C.] \texttt{LEFT JOIN} ne fonctionne que sur des tables triées
        \item[D.] \texttt{INNER JOIN} est plus rapide que \texttt{LEFT JOIN}
    \end{itemize}
\end{frame}

% Q24 - Réponse en A
\begin{frame}[fragile]{Question 24 \textemdash{} Problème de concurrence}
    Sans isolation des transactions, deux transactions
simultanées qui modifient le même compte bancaire peuvent
provoquer :\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Une perte de mise à jour : l'effet d'une transaction est annulé par l'autre, faisant disparaître un dépôt}
        \item[B.] Une erreur de syntaxe SQL
        \item[C.] Une duplication automatique des données
        \item[D.] Une accélération de l'exécution des deux transactions
    \end{itemize}
\end{frame}

% Q25 - Réponse en A
\begin{frame}[fragile]{Question 25 \textemdash{} Index}
    Pourquoi crée-t-on des \textbf{index} sur les colonnes
fréquemment utilisées dans des \texttt{WHERE} ou des jointures ?\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Pour accélérer la recherche en évitant un parcours complet de la table}
        \item[B.] Pour économiser de l'espace de stockage
        \item[C.] Pour rendre les données automatiquement triées
        \item[D.] Pour chiffrer les données sensibles
    \end{itemize}
\end{frame}

% Q26 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 26 \textemdash{} Regroupement avec GROUP BY}
    Pour obtenir le \textbf{nombre d'élèves par classe} dans la
table \texttt{eleves(id, nom, classe)}, quelle requête utiliser ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves;
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
SELECT DISTINCT classe, COUNT(*)
FROM eleves;
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
SELECT classe, COUNT(eleves)
FROM eleves
GROUP BY classe;
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
GROUP BY classe;
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q26 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 26 \textemdash{} Regroupement avec GROUP BY}
    Pour obtenir le \textbf{nombre d'élèves par classe} dans la
table \texttt{eleves(id, nom, classe)}, quelle requête utiliser ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves;
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
SELECT DISTINCT classe, COUNT(*)
FROM eleves;
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
SELECT classe, COUNT(eleves)
FROM eleves
GROUP BY classe;
\end{lstlisting}

        \item[\alert{D.}]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
GROUP BY classe;
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q27 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 27 \textemdash{} HAVING vs WHERE}
    Pour ne garder que les classes ayant \textbf{au moins
$25$ élèves}, on doit filtrer un résultat agrégé. Quelle
est la requête correcte ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
SELECT classe
FROM eleves
GROUP BY classe
WHERE COUNT(*) >= 25;
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
WHERE COUNT(*) >= 25
GROUP BY classe;
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
HAVING classe COUNT(*) >= 25;
\end{lstlisting}

        \item[D.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
GROUP BY classe
HAVING COUNT(*) >= 25;
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q27 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 27 \textemdash{} HAVING vs WHERE}
    Pour ne garder que les classes ayant \textbf{au moins
$25$ élèves}, on doit filtrer un résultat agrégé. Quelle
est la requête correcte ?\medskip
    \begin{itemize}
        \item[A.]~\\
\begin{lstlisting}
SELECT classe
FROM eleves
GROUP BY classe
WHERE COUNT(*) >= 25;
\end{lstlisting}

        \item[B.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
WHERE COUNT(*) >= 25
GROUP BY classe;
\end{lstlisting}

        \item[C.]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
HAVING classe COUNT(*) >= 25;
\end{lstlisting}

        \item[\alert{D.}]~\\
\begin{lstlisting}
SELECT classe, COUNT(*)
FROM eleves
GROUP BY classe
HAVING COUNT(*) >= 25;
\end{lstlisting}

    \end{itemize}
\end{frame}

% Q28 - Réponse en D
\begin{frame}[fragile]{Question 28 \textemdash{} Propriétés ACID}
    Les propriétés ACID des transactions garantissent leur
bon comportement dans un SGBD. Que désigne le « C » de
ACID ?\medskip
    \begin{itemize}
        \item[A.] Compression
        \item[B.] Confidentialité
        \item[C.] Connexion
        \item[\alert<2>{D.}] \alert<2>{Cohérence}
    \end{itemize}
\end{frame}

% Q29 - Réponse en D
\begin{frame}[fragile]{Question 29 \textemdash{} DROP, DELETE, TRUNCATE}
    Quelle est la différence entre \texttt{DROP TABLE eleves},
\texttt{DELETE FROM eleves} et \texttt{TRUNCATE TABLE eleves} ?\medskip
    \begin{itemize}
        \item[A.] Aucune n'est valide en SQL standard

        \item[B.] \texttt{DROP} et \texttt{DELETE} sont identiques ; seul
\texttt{TRUNCATE} est différent (il vide aussi les
fichiers de log)

        \item[C.] Les trois commandes sont équivalentes

        \item[\alert<2>{D.}] \alert<2>{\texttt{DROP TABLE} supprime la table entière (structure et
contenu) ; \texttt{DELETE FROM} (sans \texttt{WHERE}) supprime
toutes les lignes mais conserve la structure (les
contraintes et les types restent) ; \texttt{TRUNCATE TABLE}
vide rapidement le contenu en conservant la
structure (souvent plus rapide que \texttt{DELETE})
}
    \end{itemize}
\end{frame}

% Q30 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 30 \textemdash{} Trace d'une requête SELECT avec WHERE}
    On considère la table \texttt{eleves} suivante :

| id | nom    | classe | moyenne |
|----|--------|--------|---------|
| 1  | Alice  | 1A     | 14.5    |
| 2  | Bob    | 1B     | 9.0     |
| 3  | Chloé  | 1A     | 16.0    |
| 4  | David  | 1B     | 13.0    |
| 5  | Émma   | 1A     | 11.5    |

Que renvoie la requête suivante ?

\begin{lstlisting}
SELECT nom, moyenne
FROM eleves
WHERE classe = '1A' AND moyenne >= 12
ORDER BY moyenne DESC;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] Cinq lignes (toutes les lignes de la table)

        \item[B.] Trois lignes : \texttt{('Alice', 14.5)},
\texttt{('Chloé', 16.0)}, \texttt{('Émma', 11.5)}

        \item[C.] Deux lignes : \texttt{('Chloé', 16.0)} puis
\texttt{('Alice', 14.5)}

        \item[D.] Une seule ligne : \texttt{('Chloé', 16.0)}

    \end{itemize}
\end{frame}

% Q30 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 30 \textemdash{} Trace d'une requête SELECT avec WHERE}
    On considère la table \texttt{eleves} suivante :

| id | nom    | classe | moyenne |
|----|--------|--------|---------|
| 1  | Alice  | 1A     | 14.5    |
| 2  | Bob    | 1B     | 9.0     |
| 3  | Chloé  | 1A     | 16.0    |
| 4  | David  | 1B     | 13.0    |
| 5  | Émma   | 1A     | 11.5    |

Que renvoie la requête suivante ?

\begin{lstlisting}
SELECT nom, moyenne
FROM eleves
WHERE classe = '1A' AND moyenne >= 12
ORDER BY moyenne DESC;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] Cinq lignes (toutes les lignes de la table)

        \item[B.] Trois lignes : \texttt{('Alice', 14.5)},
\texttt{('Chloé', 16.0)}, \texttt{('Émma', 11.5)}

        \item[\alert{C.}] \alert{Deux lignes : \texttt{('Chloé', 16.0)} puis
\texttt{('Alice', 14.5)}
}
        \item[D.] Une seule ligne : \texttt{('Chloé', 16.0)}

    \end{itemize}
\end{frame}

% Q31 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 31 \textemdash{} Trace d'une jointure}
    On dispose des deux tables suivantes :

Table \texttt{clients} :

| id | nom    |
|----|--------|
| 1  | Alice  |
| 2  | Bob    |
| 3  | Chloé  |

Table \texttt{commandes} :

| id | client_id | produit  |
|----|-----------|----------|
| 10 | 1         | Livre    |
| 11 | 2         | Cahier   |
| 12 | 1         | Stylo    |

Combien de lignes renvoie la requête suivante ?

\begin{lstlisting}
SELECT c.nom, cmd.produit
FROM clients c
JOIN commandes cmd ON c.id = cmd.client_id;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] 2 lignes (une seule par client présent dans
les commandes)

        \item[B.] 3 lignes
        \item[C.] 9 lignes (le produit cartésien $3 \times 3$)
        \item[D.] 4 lignes
    \end{itemize}
\end{frame}

% Q31 - Réponse en B
\begin{frame}[fragile,allowframebreaks]{Question 31 \textemdash{} Trace d'une jointure}
    On dispose des deux tables suivantes :

Table \texttt{clients} :

| id | nom    |
|----|--------|
| 1  | Alice  |
| 2  | Bob    |
| 3  | Chloé  |

Table \texttt{commandes} :

| id | client_id | produit  |
|----|-----------|----------|
| 10 | 1         | Livre    |
| 11 | 2         | Cahier   |
| 12 | 1         | Stylo    |

Combien de lignes renvoie la requête suivante ?

\begin{lstlisting}
SELECT c.nom, cmd.produit
FROM clients c
JOIN commandes cmd ON c.id = cmd.client_id;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] 2 lignes (une seule par client présent dans
les commandes)

        \item[\alert{B.}] \alert{3 lignes}
        \item[C.] 9 lignes (le produit cartésien $3 \times 3$)
        \item[D.] 4 lignes
    \end{itemize}
\end{frame}

% Q32 - Réponse en A
\begin{frame}[fragile,allowframebreaks]{Question 32 \textemdash{} GROUP BY avec HAVING en pratique}
    Avec la table \texttt{eleves(id, nom, classe, moyenne)}
contenant trente élèves répartis entre trois
classes (\texttt{1A}, \texttt{1B}, \texttt{1C}), que renvoie la
requête suivante ?

\begin{lstlisting}
SELECT classe, AVG(moyenne) AS moy_classe
FROM eleves
GROUP BY classe
HAVING AVG(moyenne) > 12
ORDER BY moy_classe DESC;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[A.] La liste des classes dont la moyenne de
la classe est strictement supérieure à
$12$, avec leur moyenne, triée par
moyenne décroissante

        \item[B.] Une erreur SQL, car on ne peut pas mettre
un alias dans \texttt{ORDER BY}

        \item[C.] Toutes les classes, avec la somme des
moyennes des élèves

        \item[D.] La liste des élèves dont la moyenne
individuelle est supérieure à $12$

    \end{itemize}
\end{frame}

% Q32 - Réponse en A
\begin{frame}[fragile,allowframebreaks]{Question 32 \textemdash{} GROUP BY avec HAVING en pratique}
    Avec la table \texttt{eleves(id, nom, classe, moyenne)}
contenant trente élèves répartis entre trois
classes (\texttt{1A}, \texttt{1B}, \texttt{1C}), que renvoie la
requête suivante ?

\begin{lstlisting}
SELECT classe, AVG(moyenne) AS moy_classe
FROM eleves
GROUP BY classe
HAVING AVG(moyenne) > 12
ORDER BY moy_classe DESC;
\end{lstlisting}\medskip
    \begin{itemize}
        \item[\alert{A.}] \alert{La liste des classes dont la moyenne de
la classe est strictement supérieure à
$12$, avec leur moyenne, triée par
moyenne décroissante
}
        \item[B.] Une erreur SQL, car on ne peut pas mettre
un alias dans \texttt{ORDER BY}

        \item[C.] Toutes les classes, avec la somme des
moyennes des élèves

        \item[D.] La liste des élèves dont la moyenne
individuelle est supérieure à $12$

    \end{itemize}
\end{frame}

% Q33 - Réponse en A
\begin{frame}[fragile]{Question 33 \textemdash{} Notion de vue}
    Une \textbf{vue} (\texttt{VIEW}) en SQL est :\medskip
    \begin{itemize}
        \item[\alert<2>{A.}] \alert<2>{Une requête nommée dont le résultat se
comporte comme une table virtuelle :
chaque interrogation de la vue
réexécute la requête sous-jacente sur les
données actuelles
}
        \item[B.] Une représentation graphique des relations
entre les tables

        \item[C.] Un type particulier d'index pour accélérer
les recherches

        \item[D.] Une copie figée des données à un instant
donné

    \end{itemize}
\end{frame}

% Q34 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 34 \textemdash{} Lecture d'un schéma relationnel}
    On considère le schéma relationnel suivant :

\begin{lstlisting}
eleves(id_eleve, nom, prenom, id_classe#)
classes(id_classe, niveau, salle)
notes(id_eleve#, id_devoir#, note)
devoirs(id_devoir, matiere, date)
\end{lstlisting}

Le \texttt{\#} désigne une clé étrangère. Quelle
affirmation est correcte ?\medskip
    \begin{itemize}
        \item[A.] La table \texttt{eleves} n'a pas de lien avec
\texttt{classes}

        \item[B.] On peut avoir plusieurs élèves avec le
même \texttt{id\_eleve}

        \item[C.] Pour ajouter une note dans \texttt{notes}, il
n'est pas nécessaire que l'élève existe
dans \texttt{eleves}

        \item[D.] La table \texttt{notes} a une clé primaire
composite \texttt{(id\_eleve, id\_devoir)}, et ses
deux composantes sont des clés étrangères
référençant respectivement \texttt{eleves} et
\texttt{devoirs}

    \end{itemize}
\end{frame}

% Q34 - Réponse en D
\begin{frame}[fragile,allowframebreaks]{Question 34 \textemdash{} Lecture d'un schéma relationnel}
    On considère le schéma relationnel suivant :

\begin{lstlisting}
eleves(id_eleve, nom, prenom, id_classe#)
classes(id_classe, niveau, salle)
notes(id_eleve#, id_devoir#, note)
devoirs(id_devoir, matiere, date)
\end{lstlisting}

Le \texttt{\#} désigne une clé étrangère. Quelle
affirmation est correcte ?\medskip
    \begin{itemize}
        \item[A.] La table \texttt{eleves} n'a pas de lien avec
\texttt{classes}

        \item[B.] On peut avoir plusieurs élèves avec le
même \texttt{id\_eleve}

        \item[C.] Pour ajouter une note dans \texttt{notes}, il
n'est pas nécessaire que l'élève existe
dans \texttt{eleves}

        \item[\alert{D.}] \alert{La table \texttt{notes} a une clé primaire
composite \texttt{(id\_eleve, id\_devoir)}, et ses
deux composantes sont des clés étrangères
référençant respectivement \texttt{eleves} et
\texttt{devoirs}
}
    \end{itemize}
\end{frame}

% Q35 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 35 \textemdash{} Injection SQL}
    Un programme construit la requête SQL suivante
en concaténant directement la chaîne
\texttt{nom\_saisi} reçue de l'utilisateur :

\begin{lstlisting}
requete = "SELECT * FROM users WHERE nom = '" + nom_saisi + "';"
\end{lstlisting}

Si l'utilisateur saisit
\texttt{' OR '1'='1}, que se passe-t-il ?\medskip
    \begin{itemize}
        \item[A.] Le SGBD détecte l'injection et rejette la
requête

        \item[B.] Python lève une exception au moment de la
concaténation

        \item[C.] La requête devient
\texttt{SELECT * FROM users WHERE nom = '' OR '1'='1';},
ce qui sélectionne toutes les lignes
de la table : c'est une injection SQL

        \item[D.] La requête ne retourne aucune ligne

    \end{itemize}
\end{frame}

% Q35 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 35 \textemdash{} Injection SQL}
    Un programme construit la requête SQL suivante
en concaténant directement la chaîne
\texttt{nom\_saisi} reçue de l'utilisateur :

\begin{lstlisting}
requete = "SELECT * FROM users WHERE nom = '" + nom_saisi + "';"
\end{lstlisting}

Si l'utilisateur saisit
\texttt{' OR '1'='1}, que se passe-t-il ?\medskip
    \begin{itemize}
        \item[A.] Le SGBD détecte l'injection et rejette la
requête

        \item[B.] Python lève une exception au moment de la
concaténation

        \item[\alert{C.}] \alert{La requête devient
\texttt{SELECT * FROM users WHERE nom = '' OR '1'='1';},
ce qui sélectionne toutes les lignes
de la table : c'est une injection SQL
}
        \item[D.] La requête ne retourne aucune ligne

    \end{itemize}
\end{frame}

% Q36 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 36 \textemdash{} Trace d'un UPDATE ciblé}
    On part de la table \texttt{comptes} suivante :

| id | titulaire | solde |
|----|-----------|-------|
| 1  | Alice     | 1000  |
| 2  | Bob       | 500   |
| 3  | Chloé     | 2000  |

On exécute la requête suivante :

\begin{lstlisting}
UPDATE comptes
SET solde = solde * 1.05
WHERE solde >= 1000;
\end{lstlisting}

Quel est le contenu de la table après
exécution ?\medskip
    \begin{itemize}
        \item[A.] Bob est supprimé de la table

        \item[B.] Toutes les lignes voient leur solde
multiplié par $1{,}05$

        \item[C.] Alice : $1050$, Bob : $500$ (inchangé),
Chloé : $2100$

        \item[D.] La table reste inchangée car la clause
\texttt{WHERE} est trop restrictive

    \end{itemize}
\end{frame}

% Q36 - Réponse en C
\begin{frame}[fragile,allowframebreaks]{Question 36 \textemdash{} Trace d'un UPDATE ciblé}
    On part de la table \texttt{comptes} suivante :

| id | titulaire | solde |
|----|-----------|-------|
| 1  | Alice     | 1000  |
| 2  | Bob       | 500   |
| 3  | Chloé     | 2000  |

On exécute la requête suivante :

\begin{lstlisting}
UPDATE comptes
SET solde = solde * 1.05
WHERE solde >= 1000;
\end{lstlisting}

Quel est le contenu de la table après
exécution ?\medskip
    \begin{itemize}
        \item[A.] Bob est supprimé de la table

        \item[B.] Toutes les lignes voient leur solde
multiplié par $1{,}05$

        \item[\alert{C.}] \alert{Alice : $1050$, Bob : $500$ (inchangé),
Chloé : $2100$
}
        \item[D.] La table reste inchangée car la clause
\texttt{WHERE} est trop restrictive

    \end{itemize}
\end{frame}

\begin{frame}[standout]{}
    Fin de l'évaluation
\end{frame}

\end{document}
