Contexte
Durée : 2h
Environnement de travail : DB Fiddle
Pré-requis : Aucun
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Si une base de données a pour but premier d'assurer la cohérence des données stockées, elle doit aussi permettre d'y accéder efficacement.
La clause SELECT
permet de récupérer toutes les données d'une table, mais bien souvent vous n'avez besoin de récupérer qu'un fragment de ces données. En d'autres termes, vous avez besoin de poser des conditions sur les données à sélectionner : seulement les personnes qui ont plus de 30 ans, seulement les jeux-vidéos en stock, etc.
Pour des raisons de performances, il est important de savoir récupérer seulement les données dont vous avez besoin. SQL fournit un ensemble d'outils permettant de filtrer les données à renvoyer à partir d'une requête SELECT
.
Interrogation des données (SELECT FROM WHERE)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectif
Savoir récupérer des données dans une table.
Mise en situation
Supposez que vous gériez une libraire, et qu'un client vous demande de consulter tous les ouvrages d'Isaac Asimov que vous avez en stock.
Or, vous gérez des dizaines de milliers d'ouvrages, et il serait très fastidieux de rechercher à la main tous les livres écrits par Asimov.
Heureusement, SQL fournit les outils pour consulter les données d'une table en fonction d'un ou plusieurs critères, comme l'égalité d'un mot ou la supériorité d'un nombre.
Définition : Sélection
Une sélection est un type de requête du langage de manipulation de données de SQL.
Elle permet de consulter les données présentes dans les tables d'une base de données.
Syntaxe : SELECT — FROM — WHERE
Une sélection se décompose comme :
SELECT <liste d attributs projetés>
FROM <liste des tables>
WHERE <condition de la restriction>;
Exemple :
Si on dispose de la table suivante contenant les informations de personnes :
CREATE TABLE personne (
nom VARCHAR(50),
prenom VARCHAR(50),
age DECIMAL
);
On peut sélectionner les nom et prénom des personnes majeures ainsi :
SELECT nom, prenom
FROM personne
WHERE age > 18;
Syntaxe : Notation préfixée
Afin de décrire un attribut d'une relation en particulier (dans le cas d'une requête portant sur plusieurs relations notamment), on utilise la notation relation.attribut
.
Exemple :
SELECT personne.nom, personne.prenom, vol.depart
FROM personne, vol
WHERE personne.vol=vol.numero;
Syntaxe : SELECT *
Exemple :
SELECT *
FROM avion;
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
On veut consulter l’intégralité des données des sociétés.
Écrire une requête SQL permettant de réaliser cela.
SELECT *
FROM societe;
On obtient le résultat suivant :
nom | pays | activite |
Pied Piper | USA | Éditeur Logiciel |
LeapMusic | France | Éditeur Logiciel |
Aperture Science | null | Fabrication de rideaux de douche |
Black Mesa | USA | null |
On veut connaître l'ensemble des employés de ces entreprises.
Écrire une requête SQL permettant de réaliser cela.
SELECT *
FROM employe;
On obtient un résultat qui commence par :
num | nom | prenom | age | salaire | societe |
1 | Hendricks | Richard | 28 | 420000 | Pied Piper |
2 | Gilfoyle | Bertram | 29 | 399666 | Pied Piper |
3 | Dunn | Donald "Jared" | 25 | 120000 | Pied Piper |
Projection (SELECT)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectifs
Savoir récupérer les valeurs d'attributs spécifiques.
Savoir ajouter des résultats de fonction aux résultats d'une sélection.
Mise en situation
Souvent, les informations que vous voulez consulter dans une base de données sont spécifiques. Par exemple, si vous avez créé une table qui répertorie les animaux, vous aurez un attribut pour le nom commun, un pour le nom scientifique, un pour la taille moyenne, un pour le nombre de pattes, etc.
Cette table pourrait contenir des dizaines d'attributs : si vous voulez récupérer tous les animaux à six pattes, il serait pertinent de n'afficher que leur nom.
SQL fournit la syntaxe pour restreindre les résultats d'une requête de sélection aux valeurs des attributs qui vous intéressent, et permet même d'enrichir le résultat avec des valeurs extérieures à la table, comme la date du jour.
Définition : Projection
Une projection est un type de sélection où seulement une partie des attributs des tables choisies est retenue pour le résultat.
Syntaxe : Clause SELECT
Supposons que l'on ait la table suivante définie comme :
CREATE TABLE R(
p1 INTEGER,
p2 INTEGER,
--- d'autres attributs ...
pn INTEGER);
On peut projeter sur les trois premiers attributs de cette table en utilisant :
SELECT p1, p2, p3
FROM R;
Exemple : Illustration d'un projection
Ici, on ne garde que les attributs A
et C
de la table R1
.
Exemple :
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
SELECT prenom, nom
FROM parent;
prenom | nom
-----------+----------
Alexandre | Brasseur
Pierre | Brasseur
Syntaxe : Alias de table
SELECT t1.attribut1
FROM table1 t1
Syntaxe : Alias d'attribut (AS)
SELECT attribut1 AS a1, attribut2 AS a2
FROM table;
Complément : Projection de constante
Il est possible de projeter directement des constantes (on utilisera généralement un alias d'attribut pour nommer la colonne).
SELECT constante AS nom;
Cette requête renverra une table avec une seule ligne et une seule colonne à la valeur de constante.
Exemple :
SELECT p.prenom AS prenom_parent, p.nom AS nom_parent, 'parent' AS statut
FROM parent p;
prenom_parent | nom_parent | statut
---------------+------------+--------
Alexandre | Brasseur | parent
Pierre | Brasseur | parent
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
On veut connaître les nom de tous employés des entreprises.
Écrire une requête SQL permettant de réaliser cela.
SELECT nom
FROM employe;
On obtient :
nom |
---|
Hendricks |
Gilfoyle |
Dunn |
Hall |
Lake |
Gamesh |
Famous |
Jones |
null |
Johnson |
Rattmann |
null |
Freeman |
On veut connaître les activités de toutes les sociétés.
Écrire une requête SQL permettant de réaliser cela.
SELECT activite
FROM societe;
On obtient :
activite |
---|
Éditeur Logiciel |
Éditeur Logiciel |
Fabrication de rideaux de douche |
null |
Restriction (WHERE)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectif
Savoir filtrer les résultats d'une requête de sélection selon un ou plusieurs critères.
Mise en situation
SQL permet de récupérer tous les enregistrements d'une table qui répondent à une ou plusieurs conditions, comme l'égalité d'un attribut avec une constante.
Mais il y a des cas où ces conditions sont plus subtiles. Dans une table qui stocke des articles et leurs prix, il pourrait être utile de récupérer les articles dans une certaine tranche de prix, entre 5 et 10 € par exemple.
Dans cette même table, pour récupérer tous les écrans d'ordinateurs, on voudrait pouvoir faire une recherche approximative sur le nom des articles, pour récupérer tous ceux qui contiennent le mot « écran »
.
SQL fournit des opérateurs permettant de réaliser ces comparaisons plus fines.
Définition : Restriction
Une restriction est un type de sélection où l'on se restreint à des enregistrements dont les attributs vérifient une ou plusieurs conditions.
Syntaxe : Clause WHERE
SELECT *
FROM R
WHERE <condition>
Exemple :
Ici on se restreint à des enregistrements de la table R1 dont l'attribut « C »
est inférieur strictement à 20.
Introduction
La clause WHERE
d'une instruction de sélection est définie par une condition. Une telle condition s'exprime à l'aide d'opérateurs de comparaison et d'opérateurs logiques. Le résultat d'une expression de condition est toujours un booléen.
Syntaxe : Opérateurs de comparaison
Les opérateurs de comparaison sont, avec attribut A
et constante C
:
A = C
A <> C
(différence)A < C
A > C
A <= C
A >= C
P BETWEEN C1 AND C2
P IN (C1, C2, ...)
P LIKE 'chaîne'
P IS NULL
Syntaxe : Opérateurs logiques
Les opérateurs logiques sont :
OR
AND
NOT
Remarque : Opérateur LIKE
L'opérateur LIKE
'chaîne'
permet d'insérer des jokers dans l'opération de comparaison (alors que l'opérateur =
teste une égalité stricte) :
Le joker
%
désigne 0 ou plusieurs caractères quelconques.Le joker
_
désigne 1 et 1 seul caractère.
On préférera l'opérateur =
à l'opérateur LIKE
lorsque la comparaison n'utilise pas de joker.
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
Écrire une requête SQL permettant de sélectionner les employés de Pied Piper.
SELECT *
FROM employe
WHERE societe='Pied Piper';
On obtient les résultats :
num | nom | prenom | age | salaire | societe |
---|---|---|---|---|---|
1 | Hendricks | Richard | 28 | 420000 | Pied Piper |
2 | Gilfoyle | Bertram | 29 | 399666 | Pied Piper |
3 | Dunn | Donald "Jared" | 25 | 120000 | Pied Piper |
4 | Hall | Monica | 27 | 420000 | Pied Piper |
Écrire une requête SQL permettant de sélectionner les sociétés exerçant en France.
SELECT *
FROM societe
WHERE pays='France';
On obtient les résultats :
nom | pays | activite |
---|---|---|
LeapMusic | France | Éditeur Logiciel |
Jointure (JOIN ON)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectif
Savoir combiner les informations issues de plusieurs tables.
Mise en situation
Une base de données relationnelle est rarement composée d'une seule table, principalement pour éviter la duplication d'informations.
On pourra par exemple imaginer la base de données d'une messagerie instantanée, qui gère dans une table les messages, et dans une autre table les utilisateurs. Ces deux tables sont liées par une clé étrangère.
Mais cette séparation pose un problème : comment récupérer le pseudonyme de l'auteur d'un message, puisque ce pseudonyme est stocké dans une autre table que le message lui-même ?
C'est l'objet des jointures, qui permettent de combiner les données issues de plusieurs tables.
Définition : Jointure
Une jointure est un type de sélection pour consulter les données de plusieurs tables qui se base sur les valeurs jointes de certains des attributs de ces tables.
Syntaxe : Jointure par la clause ON
SELECT *
FROM R1 INNER JOIN R2
ON <condition>
Exemple :
Méthode :
Comme une jointure implique plusieurs tables, on utilise les alias de table pour simplifier l'écriture des requêtes.
Il est également fréquent d'utiliser des alias d'attribut pour différencier des attributs qui ont le même nom dans les tables jointes.
Exemple :
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
CREATE TABLE enfant (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0),
parent INTEGER NOT NULL,
FOREIGN KEY (parent) REFERENCES parent(id)
);
INSERT INTO enfant VALUES (3, 'Brasseur', 'Claude', 42, 2);
SELECT e.prenom, e.nom, p.prenom AS parent
FROM enfant e INNER JOIN parent p
ON e.parent=p.id;
prenom | nom | parent
--------+----------+--------
Claude | Brasseur | Pierre
Syntaxe : Jointure par la clause WHERE
On peut aussi écrire une jointure comme la composition d'un produit et d'une restriction :
SELECT *
FROM R1, R2, Ri
WHERE <condition>
Avec condition
permettant de joindre des attributs des Ri
Complément :
Le mot-clé INNER
est optionnel car c'est le mode par défaut d'une jointure (on parle de jointure interne), on peut donc également écrire :
SELECT *
FROM R1 JOIN R2
ON <condition>
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
Écrire une requête SQL permettant de sélectionner les noms des employés avec le pays de leur entreprise.
On ne retournera pas les lignes correspondant à des employés qui n'ont pas de nom.
SELECT e.nom AS nom_employe, s.pays AS pays_societe
FROM employe e INNER JOIN societe s
ON e.societe=s.nom
WHERE e.nom IS NOT NULL;
On obtient le résultat suivant :
Nom_Employe | Pays_Societe |
---|---|
Hendricks | USA |
Gilfoyle | USA |
Dunn | USA |
Aperture Science | USA |
Lake | France |
Gamesh | France |
Famous | France |
Jones | France |
Johnson | |
Rattmann | |
Freeman | USA |
Écrire une requête SQL permettant de sélectionner l'âge des employés de Black Mesa.
SELECT e.age AS nom_employe, s.nom AS nom_societe
FROM employe e INNER JOIN societe s
ON e.societe=s.nom
WHERE s.nom = 'Black Mesa';
On obtient le résultat suivant :
Age_Employe | Nom_Societe |
---|---|
42 | Black Mesa |
34 | Black Mesa |
Opérateurs ensemblistes
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectifs
Comprendre l'analogie entre table et ensemble.
Savoir réaliser des opérations ensemblistes sur des tables.
Mise en situation
Imaginez que vous gériez une base de données qui liste tous les langages de programmation. Vous décidez d'effectuer votre découpage en tables, selon le type du langage : impératif, comme C, déclaratif, comme SQL, événementiel, comme JavaScript, etc. Vous obtenez donc une table par type de langage.
Mais certains langages ont plusieurs types ! Par exemple, JavaScript est à la fois impératif et événementiel.
Comment faire pour récupérer tous les langages qui sont à la fois impératifs et événementiels ? Cette opération est très facile si on utilise les opérateurs ensemblistes.
Introduction
On peut voir les tables comme des ensembles sur lesquels on peut réaliser des opérations ensemblistes. Pour ce faire, on utilise des opérateurs ensemblistes.
Syntaxe : Union
SELECT * FROM R1
UNION
SELECT * FROM R2
Exemple :
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
CREATE TABLE enfant (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO enfant VALUES (2, 'Brasseur', 'Pierre', 67);
INSERT INTO enfant VALUES (3, 'Brasseur', 'Claude', 42);
SELECT *
FROM enfant
UNION
SELECT *
FROM parent;
id | nom | prenom | age
----+----------+-----------+-----
2 | Brasseur | Pierre | 67
3 | Brasseur | Claude | 42
1 | Brasseur | Alexandre | 91
Remarque : Dédoublonnage
Par défaut UNION
supprime les doublons, la clause UNION ALL
permet de conserver les doublons.
Attention :
Pour qu'un opérateur ensembliste soit valide il est nécessaire que les deux relations membres aient le même schéma.
Exemple :
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
CREATE TABLE enfant (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0),
parent INTEGER NOT NULL,
FOREIGN KEY (parent) REFERENCES parent(id)
);
INSERT INTO enfant VALUES (2, 'Brasseur', 'Pierre', 67, 1);
INSERT INTO enfant VALUES (3, 'Brasseur', 'Claude', 42, 2);
/** Cette requête renvoie une erreur car les schémas ne sont pas identiques. */
SELECT *
FROM enfant
UNION
SELECT *
FROM parent;
/** Cette requête fonctionne car après la projection les schémas sont identiques. */
SELECT id, nom, prenom, age
FROM enfant
UNION
SELECT id, nom, prenom, age
FROM parent;
Syntaxe : Intersection
SELECT * FROM R1
INTERSECT
SELECT * FROM R2
Exemple :
SELECT id, nom, prenom, age
FROM enfant
INTERSECT
SELECT id, nom, prenom, age
FROM parent;
id | nom | prenom | age
----+----------+--------+-----
2 | Brasseur | Pierre | 67
Syntaxe : Différence
SELECT * FROM R1
EXCEPT
SELECT * FROM R2
Exemple :
SELECT id, nom, prenom, age
FROM enfant
EXCEPT
SELECT id, nom, prenom, age
FROM parent;
id | nom | prenom | age
----+----------+--------+-----
3 | Brasseur | Claude | 42
Remarque :
Les opérations INTERSECT
et EXCEPT
n'existent que dans la norme SQL2, et non dans la norme SQL1. Certains SGBD sont susceptibles de ne pas les implémenter.
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
Écrire une requête SQL permettant de sélectionner les prénoms des employés de l'entreprise LeapMusic.
SELECT employe.prenom
FROM employe JOIN societe
ON employe.societe=societe.nom
WHERE societe.nom='LeapMusic';
On obtient :
prenom |
Marty |
Jul |
PokeMe |
Eddy |
Écrire une requête SQL permettant de sélectionner les noms des employés de l'entreprise Aperture Science.
SELECT employe.nom
FROM employe JOIN societe
ON employe.societe=societe.nom
WHERE societe.nom='Aperture Science';
On obtient :
nom |
Johnson |
Rattmann |
Écrire une requête SQL permettant de sélectionner les prénoms des employés de l'entreprise Leap Music et les noms des employés de l'entreprise Aperture Science.
SELECT employe.prenom
FROM employe JOIN societe
ON employe.societe=societe.nom
WHERE societe.nom='LeapMusic'
UNION
SELECT employe.nom
FROM employe JOIN societe
ON employe.societe=societe.nom
WHERE societe.nom='Aperture Science';
On obtient :
prenom |
Eddy |
Johnson |
Jul |
Marty |
PokeMe |
Rattmann |
Tri (ORDER BY) et dédoublonnage (SELECT DISTINCT)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Objectifs
Savoir trier les résultats d'une requête SQL.
Savoir enlever les doublons des résultats d'une requête SQL.
Mise en situation
Les enregistrements d'une table ne sont pas ordonnés, ce qui implique que l'ordre des résultats d'une requête de sélection n'est pas prévisible.
Or il peut être très utile de trier les résultats selon un critère, par exemple pour afficher les articles en stock, en allant des prix les plus bas aux pris les plus hauts.
Aussi, lorsque l'on ne récupère que quelques attributs d'une table, comme le nom d'une personne, il y des risques de doublons. Comment supprimer ces doublons de l'affichage ?
SQL fournit des instructions pour le tri et le dédoublonnage des résultats.
Fondamental : Tri des enregistrement
On peut trier les résultats de sélection en fonction des valeurs de certains attributs des enregistrements retournés.
Syntaxe : ORDER BY
SELECT liste d'attributs projetés
FROM liste de relations
WHERE condition
ORDER BY liste ordonnée d'attributs
Les tuples sont triés d'abord par le premier attribut spécifié dans la clause ORDER BY
, puis en cas de doublons par le second, etc.
Exemple :
SELECT *
FROM parent
ORDER BY nom, age;
Remarque : Tri décroissant
Le tri défini à l'aide de ORDER BY
est un tri croissant. Pour effectuer un tri décroissant on fait suivre l'attribut du mot-clé DESC
.
Exemple :
SELECT *
FROM parent
ORDER BY nom, age DESC;
Attention : Dédoublonnage des enregistrement
L'opérateur SELECT
n'élimine pas les doublons (i.e. les tuples identiques dans la relation résultat) par défaut. Il faut pour cela utiliser l'opérateur SELECT DISTINCT
.
Exemple :
CREATE TABLE parent (
id INTEGER PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
age INTEGER CHECK (age > 0)
);
INSERT INTO parent VALUES (1, 'Brasseur', 'Alexandre', 91);
INSERT INTO parent VALUES (2, 'Brasseur', 'Pierre', 67);
SELECT nom
FROM parent;
nom
----------
Brasseur
Brasseur
(2 rows)
SELECT DISTINCT nom
FROM parent;
nom
----------
Brasseur
(1 row)
Impossible d'accéder à la ressource audio ou vidéo à l'adresse :
La ressource n'est plus disponible ou vous n'êtes pas autorisé à y accéder. Veuillez vérifier votre accès puis recharger la vidéo.
Appliquer la notion
Soit le schéma relationnel :
Employe (#Num, Nom, Prenom, Age, Salaire, Fonction=>Fonction, Societe=>Societe)
Fonction (#Intitule, SalaireMin, SalaireMax, NbHeures)
Societe (#Nom, Pays, Activite)
On crée les tables associées et leurs enregistrements.
CREATE TABLE societe(
nom VARCHAR(50),
pays VARCHAR(50),
activite VARCHAR(50),
PRIMARY KEY (nom)
);
CREATE TABLE employe(
num INTEGER,
nom VARCHAR(50),
prenom VARCHAR(50),
age INTEGER,
salaire REAL,
societe VARCHAR(50),
PRIMARY KEY (num),
FOREIGN KEY (societe) REFERENCES societe(nom)
);
INSERT INTO societe (nom, pays, activite)
VALUES ('Pied Piper', 'USA', 'Éditeur Logiciel');
INSERT INTO societe (nom, pays, activite)
VALUES ('LeapMusic', 'France', 'Éditeur Logiciel');
INSERT INTO societe (nom, activite)
VALUES ('Aperture Science', 'Fabrication de rideaux de douche');
INSERT INTO societe(nom, pays)
VALUES ('Black Mesa', 'USA');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(1, 'Hendricks', 'Richard', 28, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(2, 'Gilfoyle', 'Bertram', 29, 399666, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(3, 'Dunn', 'Donald "Jared"', 25, 120000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(4, 'Hall', 'Monica', 27, 420000, 'Pied Piper');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(5, 'Lake', 'Marty', 28, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(6, 'Gamesh', 'Jul', 18, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(7, 'Famous', 'PokeMe', 32, 820000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(8, 'Jones', 'Eddy', 44, 420000, 'LeapMusic');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(9, Null, 'Caroline', 28, 23000, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(10, 'Johnson', 'Cave', 56, 4444444, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(11, 'Rattmann', 'Doug', 45, 1337, 'Aperture Science');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(12, Null, 'G-Man', 42, 72000, 'Black Mesa');
INSERT INTO employe (num, nom, prenom, age, salaire, societe)
VALUES(13, 'Freeman', 'Gordon', 34, 420000, 'Black Mesa');
Écrire une requête SQL qui affiche les salaires de tous les employés de manière unique et dans un ordre décroissant.
SELECT DISTINCT salaire
FROM employe
ORDER BY salaire DESC;
On obtient :
salaire |
---|
4444444 |
820000 |
420000 |
399666 |
120000 |
72000 |
23000 |
1337 |
Essentiel
Quiz
Quiz - Culture
Quels sont les termes qui se rapportent aux requêtes de sélection de données ?
Projection
Création
Contraintes
Conditions
Jointure
Restriction
Quels sont les mots-clés associés aux requêtes de sélection de données ?
TABLE
CREATE
SELECT
WHERE
DROP
ORDER
ALTER
FROM
JOIN
Quiz - Méthode
Cette requête est-elle syntaxiquement correcte ?
SELECT b.numero, b.superficie, b.perimetre, b.nb_etages
FROM batiment;
Oui
Non
Cette requête est-elle syntaxiquement correcte ?
SELECT b.numero, b.superficie, b.perimetre, b.nb_etages
FROM batiment b
ORDER BY b.numero
WHERE b.nb_etages > 0;
Oui
Non
Cette requête est-elle syntaxiquement correcte ?
SELECT DISTINCT b.nb_etages, a.rue, a.ville
FROM batiment b JOIN adresse a
ON b.id_adresse = a.id
WHERE b.nb_etages > 0
ORDER BY b.nb_etages DESC;
Oui
Non
Quiz - Code
Cette requête :
SELECT DISTINCT prix_paye
FROM paiement_loyer
WHERE code_loc='X'
INTERSECT
SELECT DISTINCT prix_paye
FROM paiement_loyer
WHERE code_loc='Y';
... contient (au moins) :
Une projection
Une restriction
Une jointure
Un tri
Un dédoublonnage
Une opération ensembliste
Cette requête :
SELECT *
FROM location l JOIN appartement a
ON l.code_appt=a.code_appt
ORDER BY l.code_appt;
... contient :
Une projection
Une restriction
Une jointure
Un tri
Un dédoublonnage
Une opération ensembliste
Quiz - Culture
Quels sont les termes qui se rapportent aux requêtes de sélection de données ?
Projection
Création
Contraintes
Conditions
Jointure
Restriction
Quels sont les mots-clés associés aux requêtes de sélection de données ?
TABLE
CREATE
SELECT
WHERE
DROP
ORDER
ALTER
FROM
JOIN
Quiz - Méthode
Oui
Non
Pour pouvoir utiliser l'alias de table b
il faut le déclarer :
SELECT b.numero, b.superficie, b.perimetre, b.nb_etages
FROM batiment b;
Oui
Non
Les clauses ORDER BY
et WHERE
ne sont pas dans le bon ordre : il faut les inverser.
SELECT b.numero, b.superficie, b.perimetre, b.nb_etages
FROM batiment b
WHERE b.nb_etages > 0
ORDER BY b.numero;
Oui
Non
Quiz - Code
Une projection
Une restriction
Une jointure
Un tri
Un dédoublonnage
Une opération ensembliste
Une projection
Une restriction
Une jointure
Un tri
Un dédoublonnage
Une opération ensembliste