L'instruction SQL permettant d'extraire des données dans une table est SELECT. Les possibilités de conditions de sélection et de traitement des enregistrements peuvent conduire à des requêtes complexes. La syntaxe générale de la requête est :
SELECT [ DISTINCT ] attributs
[ FROM relation ]
[ WHERE condition ]
[ GROUP BY attributs [ ASC | DESC ] ]
[ HAVING condition ]
[ ORDER BY attributs ]
Les différentes clauses sont :
attributs : la liste des colonnes à afficher en résultat (éventuellement les fonctions à exécuter sur les colonnes)
DISTINCT: permet d'ignorer les doublonsFROM: le nom de la table (ou des tables) , éventuellement aliasé dans laquelle (lesquelles) sélectionner les enregistrementsWHERE: les conditions de sélection que doivent respecter les enregistrementsGROUP BY: permet de grouper les résultats selon un ou plusieurs attributsHAVING: des critères de sélection sur des ensembles de valeurs d'un attributs après groupementORDER BY: tri du resultats (ASCouDESC)
Exemple 4. Exemples de requêtes SELECT
mysql> SELECT * FROM collection; +---------+---------------------------------+-------------------+ | COL_NUM | COL_NOM | COL_EDITEUR | +---------+---------------------------------+-------------------+ | 2 | Ailleurs et Demain | Robert Laffont | | 4 | Ailleurs et Demain Classiques | Robert Laffont | | 5 | Antologie de la Science Fiction | Le Livre de Poche | | 6 | Special Suspens | Robert Laffont | +---------+---------------------------------+-------------------+ 4 rows in set (0.00 sec) mysql> SELECT COL_EDITEUR FROM collection; +-------------------+ | COL_EDITEUR | +-------------------+ | Robert Laffont | | Robert Laffont | | Le Livre de Poche | | Robert Laffont | +-------------------+ 4 rows in set (0.00 sec) mysql> SELECT DISTINCT COL_EDITEUR FROM collection; +-------------------+ | COL_EDITEUR | +-------------------+ | Robert Laffont | | Le Livre de Poche | +-------------------+ 2 rows in set (0.35 sec) mysql> SELECT DISTINCT COL_EDITEUR FROM collection ORDER BY COL_EDITEUR ASC; +-------------------+ | COL_EDITEUR | +-------------------+ | Le Livre de Poche | | Robert Laffont | +-------------------+ 2 rows in set (0.00 sec)
Les prédicats de sélection de la clause WHERE sont une série de tests logiques sur la valeur des colonnes de chaque enregistrement. La requête parcourt tous les enregistrements de la table, ne renvoyant que les lignes qui satisfont aux conditions. Nous examinons ces conditions dans les paragraphes suivant.
Il est possible d'intégrer des calculs ou des opérations logiques dans les prédicats de sélection et dans l'affichage des résultats. Les tableaux suivants résument ces opérateurs et fonctions :
Tableau 2. Opérateurs
| Opérateur | Symbole |
| Arithmétiques | +, -, *, /, % |
| Relationnels | <, <=, =, >, >=, <>, LIKE |
| Logiques | AND, OR, NOT, BETWEEN, IN
|
mysql> SELECT * FROM auteur
-> WHERE AUT_NOM = "HERBERT";
+---------+---------+------------+--------------------+
| AUT_NUM | AUT_NOM | AUT_PRENOM | AUT_DATE_NAISSANCE |
+---------+---------+------------+--------------------+
| 1 | HERBERT | Brian | 1944-10-12 |
| 3 | HERBERT | Frank | 1920-10-08 |
+---------+---------+------------+--------------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM collection
-> WHERE COL_NOM LIKE "AIllEUrs%";
+---------+-------------------------------+----------------+
| COL_NUM | COL_NOM | COL_EDITEUR |
+---------+-------------------------------+----------------+
| 2 | Ailleurs et Demain | Robert Laffont |
| 4 | Ailleurs et Demain Classiques | Robert Laffont |
+---------+-------------------------------+----------------+
2 rows in set (0.00 sec)
Tableau 3. Fonctions sur les chaînes de caractères
| Fonction | Description |
TRIM(x) | Supprime les espaces de début et de fin de chaîne |
LOWER(x) | Converti en minuscules |
UPPER(x) | Converti en majuscules |
LOCATE(x,y) | Renvoie la position de lpremière occurence de x dans y, 0 si pas trouvé |
CONCAT(x,y,...) | Concatène les arguments |
SUBSTRING(s,i,n) | Retourne les n derniers caractères de s à partir de i |
SOUNDEX(x) | Retourne une présentation phonétique de x |
LENGTH(x) | Renvoi la longueur de x |
mysql> SELECT AUT_NOM, AUT_PRENOM, UPPER(CONCAT(SUBSTRING(AUT_NOM,1,1) , SUBSTRING(AUT_PRENOM,1 ,1))) AS INITIALES
-> FROM auteur;
+----------+------------+-----------+
| AUT_NOM | AUT_PRENOM | INITIALES |
+----------+------------+-----------+
| HERBERT | Brian | HB |
| ANDERSON | Kevin | AK |
| HERBERT | Frank | HF |
+----------+------------+-----------+
3 rows in set (0.00 sec)
Tableau 4. Fonctions sur les dates et heures
| Fonction | Description |
NOW() | Retourne la date et heure du jour |
TO_DAYS(x) | Conversion de la date X en nombre de jours depuis la date 0 |
DAYOFWEEK(x) | Retourne un entier indiquant la position de la date dans la semaine |
DAYOFMONTH(x) | Retourne un entier indiquant la position de la date dans le mois |
DAYOFYEAR(x) | Retourne un entier indiquant la position de la date dans l'année |
SECOND(x), MINUTE(x),HOUR(x), MONTH(x),YEAR(x), WEEK(x)
| Retournent respectivement les secondes, minutes, heures, mois, anné et semaine de la ate. |
mysql> SELECT * FROM auteur
-> WHERE YEAR(AUT_DATE_NAISSANCE) > 1940;
+---------+----------+------------+--------------------+
| AUT_NUM | AUT_NOM | AUT_PRENOM | AUT_DATE_NAISSANCE |
+---------+----------+------------+--------------------+
| 1 | HERBERT | Brian | 1944-10-12 |
| 2 | ANDERSON | Kevin | 1962-03-27 |
+---------+----------+------------+--------------------+
2 rows in set (0.00 sec)
Tableau 5. Fonctions d'agrégation
| Fonction | Symbole |
COUNT([DISTINCT]x,y,...) | Compte le nombre de lignes renvoyées par une requêtes |
MIN(x), MAX(x), AVG(x), SUM(x) | Calculent respectivement le minimum, le maximum, la moyenne et la somme des valeurs de l'attribut X |
mysql> SELECT COUNT(*) as NB_AUTEURS FROM auteur; +------------+ | NB_AUTEURS | +------------+ | 3 | +------------+ 1 row in set (0.00 sec)
Tableau 6. Fonctions mathématiques
| Fonction | Description |
ABS(x) | Valeur absolue de X |
SIGN(x) | Signe de X, retourne -1, 0 ou 1 |
FLOOR(x) | Arrondi à l'entier inférieur |
CEILING(x) | Arrondi à l'entier supérieur |
ROUND(x) | Arrondi à l'entier le plus proche |
EXP(x), LOG(x), SIN(x),COS(x), TAN(x), PI() | Exponentiel, logarithme, sinus ... |
POW(x,y) | Retourne X à la puissance Y |
RAND(x) | Retourne un nombre aléatoire entre 0 et X |
TRUNCATE(x,y) | Tronque le nombre X à la Yème décimale |
SQL dispose de fonctions d'agrégats vues dans la paragraphe précédents : MAX, MIN, SUM, AVG, COUNT. Elles permettent d'effectuer des calculs statistiques sur des lignes résultant de requêtes de sélection, et sont souvent employées avec la clause GROUP BY, permettant d'opérer ces calculs sur des sous-ensembles de lignes.
De manière générale on peut dire que le GROUP BY doit porter sur l'ensemble des attributs listés hors des fonctions d'agrégats :
mysql> SELECT COUNT(COL_NOM), COL_EDITEUR
-> FROM collection
-> GROUP BY COL_EDITEUR;
+----------------+-------------------+
| COUNT(COL_NOM) | COL_EDITEUR |
+----------------+-------------------+
| 1 | Le Livre de Poche |
| 3 | Robert Laffont |
+----------------+-------------------+
2 rows in set (0.00 sec)
mysql> select count(LIV_NUM) as NB_LIV, COL_NOM, COL_EDITEUR
-> FROM livre
-> JOIN collection
-> ON collection.COL_NUM = livre.COL_NUM
-> GROUP BY COL_NOM, COL_EDITEUR;
+--------+-------------------------------+----------------+
| NB_LIV | COL_NOM | COL_EDITEUR |
+--------+-------------------------------+----------------+
| 8 | Ailleurs et Demain | Robert Laffont |
| 2 | Ailleurs et Demain Classiques | Robert Laffont |
+--------+-------------------------------+----------------+
2 rows in set (0.00 sec)
mysql> select count(LIV_NUM) as NB_LIV, COL_NOM, COL_EDITEUR
-> FROM collection -> LEFT JOIN livre
-> ON collection.COL_NUM = livre.COL_NUM
-> GROUP BY COL_NOM, COL_EDITEUR
;+--------+---------------------------------+-------------------+
| NB_LIV | COL_NOM | COL_EDITEUR |
+--------+---------------------------------+-------------------+
| 8 | Ailleurs et Demain | Robert Laffont |
| 2 | Ailleurs et Demain Classiques | Robert Laffont |
| 0 | Antologie de la Science Fiction | Le Livre de Poche |
| 0 | Special Suspens | Robert Laffont |
+--------+---------------------------------+-------------------+
4 rows in set (0.00 sec)
Le groupage des résultats se faisant après la sélection des données, il n'est pas possible de fixer des contraintes sur les fonctions d'agrégats dans la clause WHERE. HAVING permet ainsi d'éffectuer des sélections sur les calculs statistiques :
mysql> SELECT AUT_NOM, AUT_PRENOM, COUNT(ECR_NUM_LIVRE) AS NB_LIVRES
-> FROM auteur, ecrit
-> WHERE auteur.AUT_NUM = ecrit.ECR_NUM_AUTEUR
-> GROUP BY AUT_NOM, AUT_PRENOM;
+----------+------------+-----------+
| AUT_NOM | AUT_PRENOM | NB_LIVRES |
+----------+------------+-----------+
| ANDERSON | Kevin | 1 |
| HERBERT | Brian | 4 |
| HERBERT | Frank | 2 |
+----------+------------+-----------+
3 rows in set (0.00 sec)
mysql> SELECT AUT_NOM, AUT_PRENOM, COUNT(ECR_NUM_LIVRE) AS NB_LIVRES
-> FROM auteur, ecrit
-> WHERE auteur.AUT_NUM = ecrit.ECR_NUM_AUTEUR
-> AND NB_LIVRES > 2
-> GROUP BY AUT_NOM, AUT_PRENOM;
ERROR 1054 (42S22): Unknown column 'NB_LIVRES' in 'where clause'
mysql> SELECT AUT_NOM, AUT_PRENOM, COUNT(ECR_NUM_LIVRE) AS NB_LIVRES
-> FROM auteur, ecrit
-> WHERE auteur.AUT_NUM = ecrit.ECR_NUM_AUTEUR
-> GROUP BY AUT_NOM, AUT_PRENOM
-> HAVING NB_LIVRES > 2;
+---------+------------+-----------+
| AUT_NOM | AUT_PRENOM | NB_LIVRES |
+---------+------------+-----------+
| HERBERT | Brian | 4 |
+---------+------------+-----------+
1 row in set (0.00 sec)Exercice : Lister les livres qui ont été co-écrits.
Il n'est pas possible de combiner les fonctions d'agrégats entre elles :
mysql> SELECT AUT_NOM, AUT_PRENOM, MAX(COUNT(ECR_NUM_LIVRE)) AS NB_LIVRES
-> FROM auteur, ecrit
-> WHERE auteur.AUT_NUM = ecrit.ECR_NUM_AUTEUR
-> GROUP BY AUT_NOM, AUT_PRENOM;
ERROR 1111 (HY000): Invalid use of group functionConnaître l'auteur dont on a le plus d'ouvrages dans la base nécessite l'emploi de sous-requêtes, que nous allons voir dans le prochain chapitre.
Les jointures sont l'opération algébrique qui consiste à recouper les enregistrements de plusieurs tables de manière à retrouver les dépendances exprimées dès le modèle conceptuel des données. Une première méthode pour les jointures consistent à indiquer dans les prédicats de sélection l'égalité d'attributs (généralement la clef primaire et la clef étrangère) :
mysql> SELECT COL_NOM, LIV_TITRE, LIV_SS_TITRE FROM livre, collection
-> WHERE livre.COL_NUM = collection.COL_NUM;
+-------------------------------+------------------------+-------------------------+
| COL_NOM | LIV_TITRE | LIV_SS_TITRE |
+-------------------------------+------------------------+-------------------------+
| Ailleurs et Demain | Dune | |
| Ailleurs et Demain | Dune | Le Messie de Dune |
| Ailleurs et Demain | Dune | L'empereur Dieu de Dune |
| Ailleurs et Demain | Dune | Les hérétiques de Dune |
| Ailleurs et Demain | Dune | Les enfants de Dune |
| Ailleurs et Demain | Dune, la génèse | La Guerre des machines |
| Ailleurs et Demain | Dune, la génèse | Le Jihad Butlérien |
| Ailleurs et Demain | Dune, la génèse | La Bataille de Corrin |
| Ailleurs et Demain Classiques | L'Effet Lazare | |
| Ailleurs et Demain Classiques | L'Homme de deux mondes | |
+-------------------------------+------------------------+-------------------------+
10 rows in set (0.00 sec)
Les attributs portant le même nom dans les deux tables, nous sommes obligés de les préfixer du nom de chaque table.
Les requêtes utilisant souvent des jointures, MySQL implémente ces opérations de manière optimisé en utilisant la clause JOIN :
SELECT attributs FROM table1 INNER JOIN table1 ON table1.att1 = table2.att2
mysql> SELECT * FROM collection;
+---------+---------------------------------+-------------------+
| COL_NUM | COL_NOM | COL_EDITEUR |
+---------+---------------------------------+-------------------+
| 2 | Ailleurs et Demain | Robert Laffont |
| 4 | Ailleurs et Demain Classiques | Robert Laffont |
| 5 | Antologie de la Science Fiction | Le Livre de Poche |
| 6 | Special Suspens | Robert Laffont |
+---------+---------------------------------+-------------------+
4 rows in set (0.00 sec)
mysql> SELECT COL_NOM, LIV_TITRE, LIV_SS_TITRE FROM collection
-> INNER JOIN livre
-> ON collection.COL_NUM = livre.COL_NUM;
+-------------------------------+------------------------+-------------------------+
| COL_NOM | LIV_TITRE | LIV_SS_TITRE |
+-------------------------------+------------------------+-------------------------+
| Ailleurs et Demain | Dune | |
| Ailleurs et Demain | Dune | Le Messie de Dune |
| Ailleurs et Demain | Dune | L'empereur Dieu de Dune |
| Ailleurs et Demain | Dune | Les hérétiques de Dune |
| Ailleurs et Demain | Dune | Les enfants de Dune |
| Ailleurs et Demain | Dune, la génèse | La Guerre des machines |
| Ailleurs et Demain | Dune, la génèse | Le Jihad Butlérien |
| Ailleurs et Demain | Dune, la génèse | La Bataille de Corrin |
| Ailleurs et Demain Classiques | L'Effet Lazare | |
| Ailleurs et Demain Classiques | L'Homme de deux mondes | |
+-------------------------------+------------------------+-------------------------+
10 rows in set (0.00 sec)
Dans le cas de INNER JOIN, seules les lignes de la première table étant liées avec des enregistrements de la deuxième table apparaissent. Dans l'exemple, certaines collections ne sont donc pas listées. Cette jointure est appelée jointure interne, et est la plus utilisée. Le mot clef INNER est ainsi facultatif.
Les clauses LEFT JOIN (respectivement RIGHT JOIN) permettent de lister tous les enregistrements de la première table (respectivement la deuxième), même si ils n'ont pas de correspondance dans l'autre table. Dans ce cas, l'attribut non renseigné est noté NULL.
mysql> SELECT COL_NOM, LIV_TITRE, LIV_SS_TITRE FROM collection
-> LEFT JOIN livre
-> ON collection.COL_NUM = livre.COL_NUM;
+---------------------------------+------------------------+-------------------------+
| COL_NOM | LIV_TITRE | LIV_SS_TITRE |
+---------------------------------+------------------------+-------------------------+
| Ailleurs et Demain | Dune | |
| Ailleurs et Demain | Dune | Le Messie de Dune |
| Ailleurs et Demain | Dune | L'empereur Dieu de Dune |
| Ailleurs et Demain | Dune | Les hérétiques de Dune |
| Ailleurs et Demain | Dune | Les enfants de Dune |
| Ailleurs et Demain | Dune, la génése | La Guerre des machines |
| Ailleurs et Demain | Dune, la génése | Le Jihad Butl~rien |
| Ailleurs et Demain | Dune, la génése | La Bataille de Corrin |
| Ailleurs et Demain Classiques | L'Effet Lazare | |
| Ailleurs et Demain Classiques | L'Homme de deux mondes | |
| Antologie de la Science Fiction | NULL | NULL |
| Special Suspens | NULL | NULL |
+---------------------------------+------------------------+-------------------------+
12 rows in set (0.00 sec)
mysql> SELECT * FROM auteur;
+---------+------------+------------+--------------------+
| AUT_NUM | AUT_NOM | AUT_PRENOM | AUT_DATE_NAISSANCE |
+---------+------------+------------+--------------------+
| 1 | HERBERT | Brian | 1944-10-12 |
| 2 | ANDERSON | Kevin | 1962-03-27 |
| 3 | HERBERT | Frank | 1920-10-08 |
| 4 | Stephenson | Neil | 1957-09-05 |
+---------+------------+------------+--------------------+
4 rows in set (0.00 sec)
mysql> select AUT_NOM, AUT_PRENOM, LIV_TITRE ,LIV_SS_TITRE FROM livre
-> RIGHT JOIN ecrit
-> ON ecrit.ECR_NUM_LIVRE=livre.LIV_NUM
-> RIGHT JOIN auteur
-> ON ecrit.ECR_NUM_AUTEUR = auteur.AUT_NUM ;
+------------+------------+------------------------+------------------------+
| AUT_NOM | AUT_PRENOM | LIV_TITRE | LIV_SS_TITRE |
+------------+------------+------------------------+------------------------+
| HERBERT | Brian | Dune, la génése | La Guerre des machines |
| HERBERT | Brian | Dune, la génése | Le Jihad Butlérien |
| HERBERT | Brian | L'Homme de deux mondes | |
| ANDERSON | Kevin | NULL | NULL |
| HERBERT | Frank | L'Effet Lazare | |
| HERBERT | Frank | L'Homme de deux mondes | |
| Stephenson | Neil | NULL | NULL |
+------------+------------+------------------------+------------------------+
7 rows in set (0.00 sec)Pour des raisons de lisibilité des requêtes, il est préférable de n'utiliser que la syntaxe LEFT. Cette jointure est appelée jointure externe.
Les jointures externes sont également utilisées pour permettre de détecter les lignes d'une table n'ayant pas de correspondance dans une autre :
mysql> SELECT AUT_NOM, AUT_PRENOM FROM auteur
-> LEFT JOIN ecrit
-> ON ecrit.ECR_NUM_AUTEUR = auteur.AUT_NUM
-> WHERE ecrit.ECR_NUM_LIVRE IS NULL;
+------------+------------+
| AUT_NOM | AUT_PRENOM |
+------------+------------+
| ANDERSON | Kevin |
| Stephenson | Neil |
+------------+------------+
2 rows in set (0.00 sec)
On utilise alors le fait qu'une colonne n'ayant pas de correspondance est affichée à NULL.
Les sous-requêtes sont supportées depuis la version 4.1 de MySQL. Elles sont souvent nécessaires pour l'extraction de certaines informations depuis la base de données, mais ne devraient pas être systématiquement employées en lieu et place des jointures. Une sous-requête est une commande SELECT imbriquée dans une autre commande, une vue anonyme est une sous-requête placée dans une clause FROM.
Un des emplois classiques des sous-requêtes est d'obtenir une valeur placée dans une clause de sélection ou de restrictions d'une requête SELECT. Ainsi rechercher l'auteur le plus jeune de la base reviendrait à :
mysql> SELECT AUT_NOM, AUT_PRENOM FROM auteur
-> WHERE TO_DAYS(AUT_DATE_NAISSANCE) =
-> (SELECT MAX(TO_DAYS(AUT_DATE_NAISSANCE))
-> FROM auteur as TABLE_TMP);
+----------+------------+
| AUT_NOM | AUT_PRENOM |
+----------+------------+
| ANDERSON | Kevin |
+----------+------------+
1 row in set (0.00 sec)La sous requête est effectuée en premier, renvoyant une seule valeur, qui est intégré à la requête principale avant son exécution.
------------ TO DO : IN ---------------
Dans le cas où la sous-requête renvoie plusieurs lignes, il est possible de tester la valeur d'un attribut de la requête (dans les filtres WHERE et HAVING) en employant les mots clef :
ALL: la condition sera vérifié si la comparaison entre l'attribut et le résultat de la sous requête est vérifiée pour toutes les lignes de la sous-requêteANY: la condition sera vérifié si la comparaison entre l'attribut et le résultat de la sous requête est vérifiée pour au moins une ligne de la sous-requête
mysql> SELECT AUT_NOM, AUT_PRENOM FROM auteur
-> WHERE YEAR(AUT_DATE_NAISSANCE) >= ALL
-> (SELECT AUT_DATE_NAISSANCE FROM auteur as TABLE_TMP);
+----------+------------+
| AUT_NOM | AUT_PRENOM |
+----------+------------+
| ANDERSON | Kevin |
+----------+------------+
1 row in set (0.00 sec)Les vues anonymes permettent de faire des sélections dans des tables temporaires qui sont utilisées dans la clause FROM. Ces tables doivent être nommées, MySQL devant les stocker en mémoire afin d'exécuter la requête principal. Ainsi, touver l'auteur dont on a le plus de livres peut se faire par la requête :
mysql> SELECT AUT_NOM, AUT_PRENOM, COUNT(ECR_NUM_LIVRE) AS NB_LIVRES
-> FROM auteur, ecrit
-> WHERE auteur.AUT_NUM=ecrit.ECR_NUM_AUTEUR
-> GROUP BY AUT_NOM, AUT_PRENOM
-> HAVING NB_LIVRES =
-> (SELECT MAX(NB) FROM (
-> SELECT COUNT(ECR_NUM_LIVRE) AS NB, ECR_NUM_AUTEUR
-> FROM ecrit
-> GROUP BY ECR_NUM_AUTEUR
-> ) AS TABLE_TMP
-> );
+---------+------------+-----------+
| AUT_NOM | AUT_PRENOM | NB_LIVRES |
+---------+------------+-----------+
| HERBERT | Brian | 4 |
+---------+------------+-----------+
1 row in set (0.00 sec)
Vous devez concevoir les requêtes permettant d'obtenir les informations suivantes (vous êtes libres d'afficher les colonnes de votre choix, tant que l'énoncé est respecté) :
La liste des chambres de l'hôtel
La liste des chambres de l'hôtel ne possédant pas de bains
La liste des chambres de l'hôtel ne possédant pas de bain, et n'étant pas au RDC
La liste des chambres de l'hôtel proposant au moins 4 places de couchage
Le nombre de chambre par étage
Le nombre de chambre proposant au moins 4 places de couchage par étage
Le nombre de clientes enregistrées
La liste des mails sur le domaine Wanadoo
Modifier les adresses de manière à ajouter l'arondissement quand elles sont situées à Paris. Par exemple
75116 PARISdeviendra75116 PARIS 16.La liste des clients "professionnels"
La moyenne du prix d'une nuit sur tous les tarifs enregistrés
Le chiffre d'affaire maximum si l'hôtel avait été loué au complet tous les jours de l'année 2006
La liste des clients avec leur titre en toute lettre
La liste des factures associées aux clients avec leur titre en toute lettre
La liste des factures associées aux clients avec leur titre en toute lettre
La liste des emails en base avec les clients qui leur correspondent
La liste de tous les clients avec éventuellement leurs mails
La liste des clients dont on n'a pas de mails
Le nombre moyen de chambres par étage
La liste de toutes les factures et de leur montant total
Les détails de la facture la plus chère
Vous devez concevoir les requêtes permettant d'obtenir les informations suivantes (vous êtes libres d'afficher les colonnes de votre choix, tant que l'énoncé est respecté) :
Liste des films et de leurs acteurs
Liste des films par genre
Liste de tous les films commençant par "S", de leur genre, de leur type de support et de leurs acteurs
Liste des films disponibles dans au moins deux types de support
Somme des durées des films par genre
Genre contenant le maximum de films
Liste des acteurs et des réalisateurs
Durée moyenne d'un film de la vidéothèque
Titre de film ayant le plus grand nombre de caractères
Liste des films actuellement absents de la vidéothèque