3. Sélection de données

3.1. Sélection de données dans une table

3.1.1. Syntaxe générale de la commande SELECT

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 doublons

  • FROM : le nom de la table (ou des tables) , éventuellement aliasé dans laquelle (lesquelles) sélectionner les enregistrements

  • WHERE : les conditions de sélection que doivent respecter les enregistrements

  • GROUP BY : permet de grouper les résultats selon un ou plusieurs attributs

  • HAVING : des critères de sélection sur des ensembles de valeurs d'un attributs après groupement

  • ORDER BY : tri du resultats (ASC ou DESC)

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.

3.1.2. Opérateurs et fonctions

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érateurSymbole
Arithmétiques +, -, *, /, %
Relationnels<, <=, =, >, >=, <>, LIKE
LogiquesAND, 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

FonctionDescription
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

FonctionDescription
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

FonctionSymbole
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

FonctionDescription
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

3.2. Groupages et sous-ensembles

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 function

Connaî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.

3.3. Jointures et sous-requêtes

3.3.1. Jointures

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.

3.3.2. Sous-requêtes et vues anonymes

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ête

  • ANY : 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)

3.4. Exercices

3.4.1. Exercice d'application : gestion d'un hôtel

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é) :

  1. La liste des chambres de l'hôtel

  2. La liste des chambres de l'hôtel ne possédant pas de bains

  3. La liste des chambres de l'hôtel ne possédant pas de bain, et n'étant pas au RDC

  4. La liste des chambres de l'hôtel proposant au moins 4 places de couchage

  5. Le nombre de chambre par étage

  6. Le nombre de chambre proposant au moins 4 places de couchage par étage

  7. Le nombre de clientes enregistrées

  8. La liste des mails sur le domaine Wanadoo

  9. Modifier les adresses de manière à ajouter l'arondissement quand elles sont situées à Paris. Par exemple 75116 PARIS deviendra 75116 PARIS 16.

  10. La liste des clients "professionnels"

  11. La moyenne du prix d'une nuit sur tous les tarifs enregistrés

  12. Le chiffre d'affaire maximum si l'hôtel avait été loué au complet tous les jours de l'année 2006

  13. La liste des clients avec leur titre en toute lettre

  14. La liste des factures associées aux clients avec leur titre en toute lettre

  15. La liste des factures associées aux clients avec leur titre en toute lettre

  16. La liste des emails en base avec les clients qui leur correspondent

  17. La liste de tous les clients avec éventuellement leurs mails

  18. La liste des clients dont on n'a pas de mails

  19. Le nombre moyen de chambres par étage

  20. La liste de toutes les factures et de leur montant total

  21. Les détails de la facture la plus chère

3.4.2. Exercice de synthèse : vidéothèque

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é) :

  1. Liste des films et de leurs acteurs

  2. Liste des films par genre

  3. Liste de tous les films commençant par "S", de leur genre, de leur type de support et de leurs acteurs

  4. Liste des films disponibles dans au moins deux types de support

  5. Somme des durées des films par genre

  6. Genre contenant le maximum de films

  7. Liste des acteurs et des réalisateurs

  8. Durée moyenne d'un film de la vidéothèque

  9. Titre de film ayant le plus grand nombre de caractères

  10. Liste des films actuellement absents de la vidéothèque

Skins :
Transparence
Simple
Page Accueil
Formation