Vous êtes sur la page 1sur 14

CPGE-Alcachy Niveau MP/MP*

Langage SQL

1. Introduction

Le SQL (Structured Query Language) permet d'interroger une base de données, d'en modifier des
informations. C'est un langage universel d'interrogation des bases de données, qui permet à différents
systèmes d'échanger des données entre eux.

2. Les requêtes simples :


Soit 3 tables :
Eleves (NomElv, AdrElv, VilleElv),
Matieres (NomMat, Coef),
Notes(#NomElv, #NomMat, Date, Note).
L'interrogation simple
Liste des élèves.

SELECT NomElv (Qu'est ce que je dois afficher ?)


FROM Eleves; (Où cela se trouve t-il ?)

Liste des matières avec leurs coefficients.


SELECT NomMat, Coef
FROM Matieres;
La close WHERE
Elle permet de spécifier la ou les conditions que doivent remplir les lignes choisies.
Liste des élèves habitant Fes.
SELECT NomElv
FROM Eleves
WHERE VilleElv = 'Fes';
Liste des matières pour lesquelles l'élève "Aziz" a eu au moins une note.
SELECT NomMat
FROM Notes
WHERE NomElv = 'Aziz';
Remarque : Dans la close WHERE, on peut utiliser que des propriétés qui sont dans la table sélectionnée
La close GROUP BY

Il est possible de subdiviser la table en groupes, chaque groupe étant l'ensemble de lignes ayant une
valeur commune.

Liste des élèves par ville.

SELECT NomElv, VilleElv


FROM Eleves
GROUP BY VilleElv;
La close HAVING

A.Lagrioui Page 1/14


CPGE-Alcachy Niveau MP/MP*

Elle ne s'utilise qu'avec le GROUP BY et permet de donner la ou les conditions que doivent remplir ces
groupes.
Liste des élèves regroupés par ville où habitent plus de 10 élèves.
SELECT NomElv, VilleElv
FROM Eleves
GROUP BY VilleElv
HAVING Count(NomElv) > 10;
Liste des matières où plus de 35 notes ont été données.
SELECT NomMat
FROM Notes
GROUP BY NomMat
HAVING Count(Note) > 35;
La close ORDER BY
Elle permet de spécifier l'ordre dans lequel vont être affichées les lignes.
Liste des matières dans l'ordre alphabétique.
SELECT NomMat
FROM Matieres
ORDER BY NomMat;
Liste des matières par ordre décroissant de coef., puis par ordre alphabétique de nom.
SELECT NomMat
FROM Matires
ORDER BY Coef Desc, NomMat Asc;
Récapitulatif
SELECT noms des colonnes à afficher
FROM nom de la table où se trouvent les colonnes susmentionnées
WHERE condition(s) à remplir par les lignes
GROUP BY condition(s) de regroupement des lignes
HAVING condition(s) à remplir par le groupe
ORDER BY ordre (Asc, Desc) d'affichage

3. Les requêtes multi-tables

Soit 4 tables : Eleves(#RefElv, NomElv, PreElv, VilleElv, ClasseElv), Classes(#NomCla, Niveau),


Cours(#RefElv, #NomMat, NbHeure), Matieres(#NomMat).

Requêtes où les données sélectionnées sont dans plusieurs tables

Liste des élèves avec leur niveau.

SELECT NomElv, PreElv, Niveau


FROM Eleves, Classes
WHERE Eleves.ClasseElv = Classes.NomCla;

Liste des élèves et nom des cours qu'ils suivent pendant plus de 3 heures.

A.Lagrioui Page 2/14


CPGE-Alcachy Niveau MP/MP*

SELECT NomElv, NomMat


FROM Eleves, Cours
WHERE (Eleves.RefElv = Cours.RefElv) AND (Cours.NbHeure > 3);
(d'abord il faut faire les jointures puis après les sélections)

Requêtes où les données proviennent d'une table mais où la condition de sélection est faite sur une table
différente

Liste des élèves de 1ère.

SELECT NomElv, PreElv


FROM Eleves
WHERE ClasseElv IN (SELECT NomCla FROM Classes WHERE Niveau = '1ère');

Liste des élèves qui font de la Peinture pendant plus de 2 heures.

SELECT NomElv, PreElv


FROM Eleves
WHERE RefElv IN (SELECT RefElv FROM Cours WHERE (NomMat = 'Peinture') AND (NbHeure >
2));

Liste des élèves habitant Fes et suivant des cours de Mathématique et de niveau DUT.

SELECT NomElv, PreElv


FROM Eleves
WHERE (VilleElv = 'Fes')
AND (RefElv IN (SELECT RefElv FROM Cours WHERE (NomMat = 'Mathématique')))
AND (ClasseElv IN (SELECT NomCla FROM Classes WHERE (Niveau = 'BTS')));
Ce qu'il ne faut pas faire
Liste des élèves de niveau Terminale.

SELECT NomElv, PreElv FROM Eleves, Classes


WHERE (Eleves.ClasseElv = Classes.NomCla) AND (Niveau = 'Terminale');

Voici la bonne méthode :

SELECT NomElv, PreElv FROM Eleves


WHERE ClasseElv IN ( SELECT NomCla FROM Classes WHERE (Niveau = 'Terminale'));

Les Jointures :

 La jointure LEFT OUTER JOIN

Soit 2 tables : Clients(NomCli, AdrCli, CPCli, VilleCli, #CodeCom),

Commerciaux(CodeCom, NomCom).

On utilise LEFT OUTER JOIN pour créer une jointure externe gauche.
Prenons un cas simple avec deux tables : La jointure externe gauche se compose de tous les
enregistrements de la première table (celle de gauche) et de ceux la deuxième table (celle de droite)
seulement à la condition qu'il existe une valeur correspondante aux enregistrements de la première table
(celle de gauche).

A.Lagrioui Page 3/14


CPGE-Alcachy Niveau MP/MP*

Liste des Clients avec le nom de leurs commerciaux.

SELECT NomCli, CPCli, VilleCli, NomCom


FROM Clients LEFT OUTER JOIN Commerciaux ON Clients.CodeCom = Commerciaux.CodeCom;

Avec les tables suivantes :

CodeCom NomCom
NomCli AdrCli CPCli VilleCli CodeCom 1 Said Arabi
S. Ahmed 5 av MedV 33000 Fes 2 2 Amina Radi
J.Aziz 3 rue Ghaza 17000 Meknes 3 3 Rachid Bekri
4 Rabie Dena
On obtient le résultat suivant :
NomCli CPCli VilleCli NomCom
S.Ahmec 33000 Fes Amina Radi
J.Aziz 17000 Meknes Rachid Bekri
 La jointure RIGHT OUTER JOIN
Soit 2 tables : Clients(NomCli, AdrCli, CPCli, VilleCli, #CodeCom),
Commerciaux(CodeCom, NomCom).

On utilise RIGHT OUTER JOIN pour créer une jointure externe droite.
Prenons un cas simple avec deux tables : La jointure externe droite se compose de tous les
enregistrements de la seconde table (celle de droite) et de ceux la première table (celle de gauche)
seulement à la condition qu'il existe une valeur correspondante aux enregistrements de la deuxième table
(celle de droite).

Liste des Clients avec le nom de leurs commerciaux.

SELECT NomCli, CPCli, VilleCli, NomCom


FROM Commerciaux RIGHT OUTER JOIN Clients ON Clients.CodeCom = Commerciaux.CodeCom;

Avec les tables suivantes :

NomCli AdrCli CPCli VilleCli CodeCom CodeCom NomCom


Jalal Rue1-Fes 25000 Fes 2 1 hamza
Badr Rue1-Taza 33000 Taza 3 2 Khawla
On obtient les résultats suivants 3 Oumaima
NomCli CPCli VilleCli NomCom 4 Driss.A
Jalal 25000 Fes Khawla 5 Mbarek
Badr 33000 Taza Oumaima
Remarque : Vous avez pu remarquer que cette dernière requête est sensiblement identique à la
précédente (LEFT OUTER JOIN). A deux détails prêts : d'une part j'ai utilisé une jointure RIGHT
OUTER JOIN et d'autre part j'ai inversé l'ordre des tables Clients & Commerciaux. Au final, vous
constatez que les deux requêtes fournissent le même résultat.
 La jointure INNER JOIN
Soit 2 tables : Eleves(RefElv, NomElv, PreElv, #ClasseElv),
Classes(NomCla, Niveau).

A.Lagrioui Page 4/14


CPGE-Alcachy Niveau MP/MP*

On utilise INNER JOIN pour fusionner les enregistrements de deux tables lorsqu’un champ commun
contient des valeurs identiques.
Liste des élèves avec leurs niveaux.
SELECT RefElv, NomElv, PreElv, NomCla, Niveau
FROM Eleves INNER JOIN Classes ON Eleves.ClasseElv = Classes.NomCla;

Insertion, MAJ et Suppression


Soit 1 table : Eleves(NomElv, AdrElv, VilleElv).
 Insertion de données : INSERT INTO
Insérer l'élève "Youssef" qui habite "Avenue Far- Meknes" à la ville de "Meknes".
INSERT INTO Eleves (NomElv, AdrElv, VilleElv) VALUES ('Youssef', ' Avenue Far- Meknes,
'Meknes');
Il existe une autre syntaxe qui permet d'insérer dans une table des lignes provenant d'une autre :
INSERT INTO nom de la table1 SELECT noms des colonnes à insérer FROM nom de la table2;
 Mise à jour de données : UPDATE
Modifier le nom de l'élève "Youssef" en "Mounir".
UPDATE Eleves SET NomElv = 'Mounir' // (Nouvelle valeur)
WHERE NomElv = 'Youssef'; // (Ancienne valeur)
 Suppression de lignes de tables : DELETE
Supprimer l'élève "Youssef".
DELETE FROM Eleves WHERE NomElv = 'Youssef';
Les fonctions de groupes et d’agrégation
Les fonctions de groupes sont :
Avg (moyenne),
Count(*) (nombre de ligne),
Count(col) (nombre de valeurs non nulles de la colonnes),
Count(distinct col) (nombre de valeurs non nulles différentes),
Sum (somme),
Min, (minimum)
Max, (maximum)
Variance (variance),
Stddev (écart type : déviation standard).
Elles peuvent apparaître dans le Select ou le Having.
Une fonction d’agrégation (elle produit une valeur unique) s'applique à l'ensemble des valeurs d'une
colonne d'une table (sauf pour la fonction Count).
 L' AVG
La commande AVG permet de calculer la moyenne d'un champ
Soit une table Commandes(NumCmd, DateCmd, Désignation, FraisPort).
La moyenne des frais de port pour les commandes dont les frais sont inférieurs 150 Dh.
SELECT AVG(FraisPort)
FROM Commandes
WHERE FraisPort < 150:

A.Lagrioui Page 5/14


CPGE-Alcachy Niveau MP/MP*

 Le COUNT
La commande COUNT permet de compter les lignes.
Soit une table : Eleves(NomElv, AdrElv, VilleElv).
Le nombre d'élèves.
SELECT COUNT(NomElv)
FROM Eleves;
 Le SUM
La commande SUM fait la somme d'un champ.
Soit une table Acomptes(DateAcpt, NomOvr, Montant).
La somme des acomptes de chaque ouvrier.
SELECT NomOvr, SUM(Montant)
FROM AComptes
GROUP BY NomOvr;
 Le BETWEEN
Le BETWEEN s'utilise avec la close WHERE.
Soit une table Acomptes(DateAcpt, NomOvr, Montant).
La liste des acomptes versés entre le 01/02/2015 et le 28/06/2015.
SELECT * //(Affiche tout les champs de la table Acomptes)
FROM AComptes
WHERE DateAcpt BETWEEN '01/02/2015' AND '28/06/2015';
 Le DISTINCT
La commande DISTINCT permet de supprimer les lignes redondantes.
Soit une table : Eleves(NomElv, AdrElv, VilleElv).
La liste des villes où habitent les élèves.
SELECT DISTINCT VilleElv
FROM Eleves;
 Le LIKE
Le LIKE s'utilise avec la close WHERE.
Soit une table : Eleves(NomElv, AdrElv, VilleElv).
La liste des élèves dont le nom commence par "a" ou "A".
SELECT * (Affiche tout les champs de la table Elèves)
FROM Eleves
WHERE NomElv LIKE 'a%' OR NomElv LIKE 'A%';
Les caractères jokers sont :
 "_" remplace un caractère exactement et
 "%" remplace une chaîne de caractères de taille quelconque.

A.Lagrioui Page 6/14


CPGE-Alcachy Niveau MP/MP*

é
Vous pouvez stocker des informations dans des fichiers XML mais très rapidement, suivant
l'ampleur de votre projet, cette technologie atteindra ses limites que ce soit en termes de
performances ou d'utilisation au quotidien. Si plusieurs personnes souhaitent modifier un
fichier texte de données en même temps les erreurs seront inévitables. Il existe une solution
pour stocker des informations et pouvoir travailler: les bases de données.

Une base de données c'est quoi?


Une base de données (database en anglais) est un conteneur dans lequel il est possible
de stocker des données de façon structurée. Cette structure permet au programme
informatique connectée à celle-ci de faire des recherches complexes.
Un langage standardisé -SQL- est dédié à cette structure et permet aussi bien de faire des
recherches mais aussi des modifications ou des suppressions.
Les logiciels de gestion de bases de données les plus utilisées aujourd'hui sont des SGBDR -
Système de gestion de base de données relationnelles-, c'est à dire que les données sont liées les
unes aux autres, par exemple on peut définir que si on supprime une information, d'autres
informations dépendantes de cette dernière soient elles-aussi automatiquement supprimées.
Cela garantit une cohérence de données.
Il ne faut donc pas confondre une base de données qui est un conteneur et le SGBDR qui est
un logiciel de gestion de bases de données.

Quels sont les SGBDR les plus connus?

MySQL Mysql est l'un des SGBDR les plus utilisés au monde. Il est gratuit et très puissant.
Il possède la double licence GPL et propriétaire depuis son rachat par Sun
Microsystem eux-mêmes racheté par Oracle (concurrent direct de MySQL). Le
logiciel reste cependant entièrement gratuit et libre. Il répond à une logique
client/serveur, c'est à dire que plusieurs clients (ordinateurs distants) peuvent se
connecter sur un seul serveur qui héberge les données.

PostgreSQL PostgreSQL ressemble à MySQL, moins connu mais possède des fonctionnalités en
plus.

SQLite SQLite est une bibliothèque écrite en C. SQLite est parfait pour les petits projets. Sa
particularité est d'être intégré directement à un programme et ne répond donc pas à la
logique client-serveur. Il est le moteur de base de données le plus distribué au monde
puisqu'il est intégré à de nombreux logiciels grand public comme FireFox, Skype,
python, Adobe, etc. Le logiciel pèse moins de 300 ko et peut donc être intégré à des
projets tournant sur de petits supports comme les smartphones. Souvent aucune
installation n'est nécessaire pour l'utiliser.

Oracle Oracle Database est sous licence propriétaire, c'est à dire payant. Il est souvent utilisé
pour les projets à gros budget nécessitant de réaliser des actions complexes.

Microsoft Produit Microsoft ne tourne que sur un OS Windows, payant n'apporte rien de plus que
SQL Server les logiciels concurrents libre de droit. Si vous avez trop d'argent à la limite...

Prérequis
A.Lagrioui Page 7/14
CPGE-Alcachy Niveau MP/MP*

Pour pouvoir exploiter les bases de données que nous allons étudier, il est nécessaire de maîtriser le SQL.

SQLite :
Notre premier exemple concernera SQLite.

SQLite a été conçu pour être intégré dans le programme même. Pour des projets plus ambitieux / projets
web le choix de MySQL serait plus judicieux.

Utiliser le module SQLite


Pour importer le module SQLite:

import sqlite3

Créer une base de données avec SQLite


La aussi pour créer une base de données avec SQLite, rien de plus simple:

connexion = sqlite3.connect('ma_base.db')

Lorsque vous exécuterez votre programme vous remarquerez que si la base n'existe pas encore, un
fichier sera crée dans le dossier de votre programme. Et si celui-ci existe déjà il sera réutilisé. Vous
pouvez bien évidemment choisir l'emplacement de votre base de données en renseignant un path,
exemple: "C :/DocLagrioui/ma_base.db" . Il vous faudra cependant vérifier que le dossier existe avant
de l'utiliser.

Il est également possible de travailler avec une base de données de manière temporaire:

connexion = sqlite3.connect(':memory:')

Lorsque le travail que vous attendiez est terminé, pensez à fermer la connection vers la base:

connexion.close()

Créer une table avec SQLite


Voici un exemple de création de table:

curseur = connexion.cursor()

curseur.execute("""

CREATE TABLE IF NOT EXISTS utilisateurs(

id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,

name TEXT NOT NULL,

age INTERGER

) """)

connexion.commit()

A.Lagrioui Page 8/14


CPGE-Alcachy Niveau MP/MP*

Supprimer une table avec SQLite:

curseur = connexion.cursor()

curseur.execute(" DROP TABLE utilisateurs )

connexion.commit()

Insérer des données


Il existe plusieurs manières d'insérer des données, la plus simple étant celle-ci:

curseur.execute(""" INSERT INTO utilisateurs (name, age) VALUES(?, ?)""", ("Ahmed", 42))

Vous pouvez passer par un dictionnaire:

data = {"name" : "Ahmed", "age" : 42}

curseur.execute(""" INSERT INTO utilisateurs (name, age) VALUES (:name, :age)""", data)

Vous pouvez récupérer l'id de la ligne que vous venez d'insérer de cette manière:

id = curseur.lastrowid

print('dernier id: %d' % id)

Il est également possible de faire plusieurs insert en une seule fois avec la fonction executemany:

utilisateur = []

utilisateur.append(("Ahmed", 42))

utilisateur.append(("Lagrioui", 90))

utilisateur.append(("Sellam", 48))

curseur.executemany("""INSERT INTO utilisateurs (name, age) VALUES(?, ?)""", utilisateur)

Récupérer des données


Vous pouvez récupérer la première ligne correspondant à votre recherche à l'aide de la
fonction fetchone.

curseur.execute("""SELECT name, age FROM utilisateurs""")

utilisateur1 = curseur.fetchone()

print(utilisateur1)

Le résultat est un tuple:

('Ahmed', 42)

Vous pouvez récupérer plusieurs données de la même recherche en utilisant la fonction fetchall().

A.Lagrioui Page 9/14


CPGE-Alcachy Niveau MP/MP*
curseur.execute("""SELECT id, name, age FROM utilisateurs""")

lignes = curseur.fetchall()

for row in lignes:

print('{0} : {1} - {2}'.format(row[0], row[1], row[2]))

L'objet curseur fonctionne comme un itérateur, invoquant la méthode fetchall() automatiquement:

curseur.execute("""SELECT id, name, age FROM utilisateurs""")

for row in curseur:

print('{0} : {1}, {2}'.format(row[0], row[1], row[2]))

Pour la recherche spécifique,on utilise la même logique vu précédemment:

id = 2

curseur.execute("""SELECT id, name FROM utilisateurs WHERE id=?""", (id,))

response = cursor.fetchone()

Modifier des entrées


Pour modifier des entrées:

curseur.execute("""UPDATE utilisateurs SET age = ? WHERE id = 2""", (40,))

SQLite transactions : rollback


Pour revenir au dernier commit, utilisez la méthode rollback.

connexion.rollback()

Gestion des erreurs


Il est recommandé de toujours encadrer les opérations sur des bases de données et d'anticiper des erreurs:

import sqlite3

try:

base = sqlite3.connect('data/utilisateur.db')

curseur = base.cursor()

curseur.execute("""

CREATE TABLE utilisateurs(

id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE,

name TEXT NOT NULL,

A.Lagrioui Page 10/14


CPGE-Alcachy Niveau MP/MP*
age INTERGER ) """)

base.commit()

except sqlite3.OperationalError:

print('Erreur la table existe déjà')

except Exception as e:

print("Erreur")

base.rollback()

# raise e

finally:

base.close()

Les erreurs que vous pouvez intercepter:

Error

DatabaseError

DataError

IntegrityError

InternalError

NotSupportedError

OperationalError

ProgrammingError

InterfaceError

Warning

Exemple :

Exemple de gestion d‟une base de données „‟Gestiondecommande.db‟‟ qui contient trois tables :

Table client ( CodeC INTEGER PRIMARY KEY, NomC TEXT, VilleC TEXT)

Table produit(Refp TEXT PRIMARY KEY, NomP TEXT, PrixP real)

Table Commande (CodeC integer , Refp TEXT , quantite INTEGER)

Importer la bibliothèque sqlite3

import sqlite3

A.Lagrioui Page 11/14


CPGE-Alcachy Niveau MP/MP*

Q1 : Créer une base de données „‟gestioncommande.db‟‟

base = sqlite3.connect('gestioncommande.db')

Q2 : Créer un curseur sur la base

curseur = base.cursor()

Q3 : Définir une fonction python permettant de Créer les trois tables décrites ci-dessus

def CreateTable():

R1=”””create table if not exist Client (CodeC integer primary key unique, NomC text not
null, VilleC text); “””

R2=”””create table if not exists produit (RefP text primary key not null, NomP text, PrixP
real);”””

R3=”””create table if not exists commande(codec integer references Client(CodeC), Refp


text references Produit(RefP), quantite integer );”””

curseur.execute(R1)

curseur.execute(R2)

curseur.execute(R3)

base.commit()

Q4 : Définir une fonction python permettant d‟ajouter des données dans la table client

def LireClient(code ,nom,ville):

curseur.execute("""INSERT INTO Client (CodeC,NomC,VilleC) values (?,?,?) ;""",


(code,nom,ville))

base.commit()

Q5 : Définir une fonction python permettant d‟ajouter des données dans la table produit

def LireProduit(ref ,nom,prix):

curseur.execute("""INSERT INTO Produit (RefP,NomP,prix) VALUES (?,?,?) """,


(ref,nom,prix))

base.commit()

Q6 : Définir une fonction python permettant d‟ajouter des données dans la table commande

def LireCommande(codec , refp, quantite):

curseur3.execute("""INSERT INTO Commande (CodeC,RefP,quantite) values (?,?,?)""",


(codec, refp, quantite))

A.Lagrioui Page 12/14


CPGE-Alcachy Niveau MP/MP*

base.commit()

Q7. Ecrire une fonction principale qui appelle et teste les fonctions définies ci-haut

def menuprincipal() :

CreateTable()

LireClient(10,'Ahmed','Fes')

LireClient(12,'Oumaima','Meknes')

LireClient(14,'Aziz','Fes')

LireClient(16,'Sanae','Rabat')

LireClient(18,'Driss','Fes')

LireProduit("P1",'PC Portable',5000)

LireProduit("P2",'Souris',50)

LireProduit("P3",'Clavier',60)

LireCommande(10,"P1",12)

LireCommande(10,"P2",20)

LireCommande(10,"P3",30)

LireCommande(12,"P1",50)

LireCommande(12,"P1",40)

base.commit()

Q8. Executer les requêtes SQL suivantes:

8.1 Une requête qui permet de lister les clients de la base

curseur.execute('SELECT * FROM Client ; ')

print(" Les données de la table client :")

for e in curseur:

print ("\n")

for x in e :

print (x, end=" ")

curseur.close()

A.Lagrioui Page 13/14


CPGE-Alcachy Niveau MP/MP*

8.2 Une requête qui permet de lister les produits de la base

curseur.execute ('SELECT * FROM Produit ; ')

print(" Les données de la table produit : ")

for e in curseur:

print ("\n")

for x in e:

print (x, end=" ")

curseur.close()

8.3 Une requête qui permet de lister les commandes de la base

curseur.execute('SELECT * FROM Commande')

print(" Les données de la table produit ")

for e in curseur:

print ("\n")

for x in e:

print (x , end=" ")

curseur.close()

A.Lagrioui Page 14/14

Vous aimerez peut-être aussi