De la théorie à MySQL
Formation DWWM - 2025-2026
Comprendre les fondamentaux
Analogie : Une bibliothèque 📚
Problème : Stocker des données dans des fichiers texte
utilisateurs.txt :
--------------------
1|Marie|Dupont|marie@mail.com|25
2|Jean|Martin|jean@mail.com|30
3|Sophie|Durand|sophie@mail.com|28
Les concepts de base
Le SGBD est responsable de :
| Type | Exemples | Caractéristiques |
|---|---|---|
| Relationnel (SGBDR) |
MySQL PostgreSQL Oracle SQL Server |
Tables avec relations Langage SQL ⭐ Le plus utilisé |
| NoSQL | MongoDB Redis Cassandra |
Documents JSON Clé-valeur Très rapide |
| Graphe | Neo4j ArangoDB |
Relations complexes Réseaux sociaux |
Pourquoi MySQL ?
Alternatives similaires :
| Terme | Définition | Analogie |
|---|---|---|
| Base de données | Collection de tables | Bibliothèque |
| Table | Collection d'enregistrements | Étagère |
| Enregistrement (ligne / row / tuple) |
Une entrée dans la table | Un livre |
| Champ (colonne / field / attribut) |
Une propriété des enregistrements | Titre, auteur... |
| Clé primaire (Primary Key) |
Identifiant unique | N° ISBN |
| Clé étrangère (Foreign Key) |
Référence vers une autre table | Référence croisée |
Concevoir la structure de la BDD
Les 3 composants du MCD :
Comment identifier les entités ?
Règles pour les attributs :
Comment identifier les relations ?
Cardinalités courantes :
| Notation | Signification |
|---|---|
| 0,1 | Zéro ou un (optionnel, unique) |
| 1,1 | Exactement un (obligatoire, unique) |
| 0,n | Zéro ou plusieurs (optionnel, multiple) |
| 1,n | Un ou plusieurs (obligatoire, multiple) |
Du MCD vers les tables
Transformation MCD → MLD :
NomTable(cle_primaire, attribut1, attribut2, #cle_etrangere)
Explications :
Client(id, ...) : id est la clé primaire#id_client : référence vers Client(id)Cas : 1,1 ↔ 0,n ou 1,n ↔ 0,n
Cas : 0,n ↔ 0,n
Cas : 1,1 ↔ 0,1 ou 1,1 ↔ 1,1
Explications :
De la théorie à MySQL
Transformation MLD → MPD :
| Type | Description | Exemples |
|---|---|---|
| INT | Nombre entier | 42, -10, 1000 |
| BIGINT | Très grand entier | 9999999999 |
| DECIMAL(10,2) | Nombre décimal précis | 99.99, 149.50 |
| FLOAT / DOUBLE | Nombre à virgule | 3.14159 |
| VARCHAR(255) | Texte variable | "Marie", "email@..." |
| TEXT | Long texte | Articles, descriptions |
| DATE | Date AAAA-MM-JJ | 2024-12-30 |
| DATETIME | Date + heure | 2024-12-30 15:30:00 |
| TIMESTAMP | Date auto (création) | CURRENT_TIMESTAMP |
| BOOLEAN | Vrai/Faux (0/1) | TRUE, FALSE |
| ENUM | Liste de valeurs | 'small','medium','large' |
| Contrainte | Description | Exemple |
|---|---|---|
| PRIMARY KEY | Clé primaire (unique + not null) | id INT PRIMARY KEY |
| AUTO_INCREMENT | Incrémentation auto (1, 2, 3...) | id INT AUTO_INCREMENT |
| NOT NULL | Obligatoire (pas de valeur nulle) | nom VARCHAR(50) NOT NULL |
| UNIQUE | Valeur unique dans la table | email VARCHAR(100) UNIQUE |
| DEFAULT | Valeur par défaut | statut VARCHAR(20) DEFAULT 'actif' |
| FOREIGN KEY | Clé étrangère (référence) | FOREIGN KEY (id_client) REFERENCES client(id) |
| CHECK | Vérification condition | CHECK (age >= 18) |
CREATE TABLE client (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
telephone VARCHAR(20),
date_inscription TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
Explications ligne par ligne :
id INT PRIMARY KEY AUTO_INCREMENT : Identifiant unique auto-incrémenténom VARCHAR(50) NOT NULL : Texte max 50 caractères, obligatoireemail VARCHAR(100) NOT NULL UNIQUE : Email obligatoire et uniquetelephone VARCHAR(20) : Optionnel (pas de NOT NULL)date_inscription TIMESTAMP DEFAULT CURRENT_TIMESTAMP : Date autoENGINE=InnoDB : Moteur de stockage (supporte les clés étrangères)CHARSET=utf8mb4 : Encodage UTF-8 (accents + émojis)-- Table Client
CREATE TABLE client (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(50) NOT NULL,
prenom VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
date_inscription TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Table Categorie
CREATE TABLE categorie (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(50) NOT NULL UNIQUE,
description TEXT
);
-- Table Produit
CREATE TABLE produit (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(100) NOT NULL,
description TEXT,
prix DECIMAL(10,2) NOT NULL,
stock INT NOT NULL DEFAULT 0,
id_categorie INT NOT NULL,
FOREIGN KEY (id_categorie) REFERENCES categorie(id)
);
-- Table Commande
CREATE TABLE commande (
id INT PRIMARY KEY AUTO_INCREMENT,
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
total DECIMAL(10,2) NOT NULL,
statut ENUM('en_attente', 'validee', 'expediee', 'livree') DEFAULT 'en_attente',
id_client INT NOT NULL,
FOREIGN KEY (id_client) REFERENCES client(id)
);
-- Table Ligne de Commande
CREATE TABLE ligne_commande (
id_commande INT,
id_produit INT,
quantite INT NOT NULL,
prix_unitaire DECIMAL(10,2) NOT NULL,
PRIMARY KEY (id_commande, id_produit),
FOREIGN KEY (id_commande) REFERENCES commande(id),
FOREIGN KEY (id_produit) REFERENCES produit(id)
);
CRUD : Create, Read, Update, Delete
Les 4 opérations de base (CRUD) :
| Opération | SQL | Action |
|---|---|---|
| Create | INSERT |
Ajouter |
| Read | SELECT |
Lire |
| Update | UPDATE |
Modifier |
| Delete | DELETE |
Supprimer |
INSERT INTO nom_table (colonne1, colonne2) VALUES (valeur1, valeur2);
Explication ligne par ligne :
INSERT INTO client (nom, prenom, email)
-- ^ ^
-- | Liste des colonnes a remplir
-- Nom de la table
VALUES ('Dupont', 'Marie', 'marie@mail.com');
-- ^ ^ ^
-- | | Valeur pour "email"
-- | Valeur pour "prenom"
-- Valeur pour "nom"
-- Ajouter un nouveau client
INSERT INTO client (nom, prenom, email, password)
VALUES ('Dupont', 'Marie', 'marie@mail.com', 'hash_mdp_123');
-- Note : l'id n'est PAS specifie (AUTO_INCREMENT le genere)
-- Ajouter plusieurs produits en une seule requete
INSERT INTO produit (nom, prix, stock, id_categorie)
VALUES
('Ordinateur', 899.99, 10, 1), -- Ligne 1
('Souris', 25.50, 50, 1), -- Ligne 2
('Clavier', 45.00, 30, 1); -- Ligne 3
-- Plus rapide que 3 INSERT separés
-- Si vous donnez TOUTES les colonnes dans l'ordre de la table
INSERT INTO categorie
VALUES (NULL, 'Informatique', 'Produits informatiques');
-- ^
-- NULL = MySQL genere l'id automatiquement
-- Copier des produits d'une table vers une autre
INSERT INTO produit_archive (nom, prix, stock)
SELECT nom, prix, stock
FROM produit
WHERE stock = 0;
-- Copie tous les produits en rupture de stock
-- ❌ ERREUR : 'nom' est obligatoire (NOT NULL)
INSERT INTO client (prenom, email)
VALUES ('Marie', 'marie@mail.com');
-- Erreur : Column 'nom' cannot be null
-- ✅ CORRECT
INSERT INTO client (nom, prenom, email)
VALUES ('Dupont', 'Marie', 'marie@mail.com');
-- ❌ ERREUR : valeurs dans le mauvais ordre
INSERT INTO client (nom, prenom, email)
VALUES ('marie@mail.com', 'Dupont', 'Marie');
-- ^ ^ ^
-- email dans "nom" nom dans "prenom"...
-- ✅ CORRECT : respecter l'ordre
INSERT INTO client (nom, prenom, email)
VALUES ('Dupont', 'Marie', 'marie@mail.com');
Comment insérer depuis PHP :
<?php
// ❌ DANGEREUX - Injection SQL possible
$nom = $_POST['nom'];
$sql = "INSERT INTO client (nom) VALUES ('$nom')";
// Si $nom = "'); DROP TABLE client; --" => CATASTROPHE
// ✅ SÉCURISÉ - Prepared Statements
$nom = $_POST['nom'];
$email = $_POST['email'];
$stmt = $pdo->prepare("INSERT INTO client (nom, email) VALUES (?, ?)");
$stmt->execute([$nom, $email]);
// ^ ^
// | Valeur pour email
// Valeur pour nom
// Récupérer l'ID de la ligne insérée
$newId = $pdo->lastInsertId();
echo "Client ajouté avec l'ID : $newId";
?>
SELECT colonnes FROM table WHERE condition;
SELECT est la requête la PLUS utilisée (90% du temps) !
-- Selectionner TOUT
SELECT * FROM client;
-- Retourne TOUTES les colonnes de TOUTES les lignes
SELECT * peut être lent sur de grandes tables !-- Selectionner certaines colonnes
SELECT nom, prenom, email FROM client;
-- Retourne seulement nom, prenom et email (pas l'age, ni l'id)
-- Avec alias (renommer les colonnes dans le resultat)
SELECT
nom AS nom_famille,
prenom AS prenom_utilisateur,
email
FROM client;
-- Resultat : colonnes renommees
-- nom_famille | prenom_utilisateur | email
-- Produits a moins de 100 euros
SELECT * FROM produit WHERE prix < 100;
-- Client specifique par ID
SELECT * FROM client WHERE id = 5;
-- Recherche par email
SELECT * FROM client WHERE email = 'marie@mail.com';
| Opérateur | Signification | Exemple |
|---|---|---|
= |
Égal | WHERE id = 5 |
!= ou <> |
Différent | WHERE statut != 'annule' |
< |
Inférieur | WHERE prix < 100 |
> |
Supérieur | WHERE age > 18 |
<= |
Inférieur ou égal | WHERE stock <= 10 |
>= |
Supérieur ou égal | WHERE note >= 10 |
-- Produits chers (plus de 500 euros)
SELECT * FROM produit WHERE prix > 500;
-- Produits en rupture de stock
SELECT * FROM produit WHERE stock = 0;
-- Produits disponibles
SELECT * FROM produit WHERE stock > 0;
-- Produits entre 50 et 200 euros
SELECT * FROM produit WHERE prix BETWEEN 50 AND 200;
-- Equivalent a : WHERE prix >= 50 AND prix <= 200
-- Commandes de decembre 2024
SELECT * FROM commande
WHERE date BETWEEN '2024-12-01' AND '2024-12-31';
-- Clients avec ID 1, 5 ou 10
SELECT * FROM client WHERE id IN (1, 5, 10);
-- Equivalent a : WHERE id = 1 OR id = 5 OR id = 10
-- Produits de certaines categories
SELECT * FROM produit WHERE id_categorie IN (1, 3, 5);
-- Clients sans telephone
SELECT * FROM client WHERE telephone IS NULL;
-- Clients avec telephone
SELECT * FROM client WHERE telephone IS NOT NULL;
% = n'importe quels caractères (0 ou plus)_ = exactement 1 caractère
-- Produits contenant "phone" dans le nom
SELECT * FROM produit WHERE nom LIKE '%phone%';
-- Trouve : "iPhone", "Smartphone", "Telephone"
-- Clients dont le nom commence par "D"
SELECT * FROM client WHERE nom LIKE 'D%';
-- Trouve : "Dupont", "Durand", "Dufour"
-- Emails Gmail
SELECT * FROM client WHERE email LIKE '%@gmail.com';
-- Codes promo commencant par "PROMO"
SELECT * FROM commande WHERE code_promo LIKE 'PROMO%';
LOWER() pour ignorer la casse
-- Produits pas chers ET en stock
SELECT * FROM produit
WHERE prix < 100 AND stock > 0;
-- ^ ^
-- Condition 1 Condition 2
-- Les DEUX doivent etre vraies
-- Adultes vivant a Paris
SELECT * FROM client
WHERE age >= 18 AND ville = 'Paris';
-- Produits de Paris OU Lyon
SELECT * FROM client
WHERE ville = 'Paris' OR ville = 'Lyon';
-- ^ ^
-- Condition 1 Condition 2
-- UNE SEULE suffit
-- Produits en rupture OU stock faible
SELECT * FROM produit
WHERE stock = 0 OR stock < 5;
-- Produits pas chers de categorie 1 OU 2
SELECT * FROM produit
WHERE prix < 100 AND (id_categorie = 1 OR id_categorie = 2);
-- ^ ^
-- Parentheses obligatoires pour l'ordre
-- Trier par prix croissant (du moins cher au plus cher)
SELECT * FROM produit ORDER BY prix ASC;
-- ^
-- ASC = Ascendant (croissant)
-- Trier par prix decroissant (du plus cher au moins cher)
SELECT * FROM produit ORDER BY prix DESC;
-- ^
-- DESC = Descendant (decroissant)
-- Trier par plusieurs colonnes
SELECT * FROM produit
ORDER BY id_categorie ASC, prix DESC;
-- ^ ^
-- D'abord par Puis par prix
-- categorie (dans chaque categorie)
-- Les 10 premiers produits
SELECT * FROM produit LIMIT 10;
-- Les 5 produits les plus chers
SELECT * FROM produit
ORDER BY prix DESC
LIMIT 5;
-- ^
-- Les 5 premiers apres tri
-- Pagination : 10 produits a partir du 20e
SELECT * FROM produit
LIMIT 10 OFFSET 20;
-- ^ ^
-- Nombre Sauter les 20 premiers
-- Utilise pour page 3 (si 10 par page)
-- Page 1 : LIMIT 10 OFFSET 0
-- Page 2 : LIMIT 10 OFFSET 10
-- Page 3 : LIMIT 10 OFFSET 20
-- Formule : OFFSET = (page - 1) * parPage
Requête avec toutes les clauses :
SELECT nom, prix, stock -- 1. Colonnes a selectionner
FROM produit -- 2. Table source
WHERE prix < 200 AND stock > 0 -- 3. Filtrer les lignes
ORDER BY prix ASC -- 4. Trier les resultats
LIMIT 10; -- 5. Limiter a 10 resultats
-- Ordre d'execution (important) :
-- 1. FROM : Prendre la table "produit"
-- 2. WHERE : Filtrer (prix < 200 ET stock > 0)
-- 3. ORDER BY: Trier par prix croissant
-- 4. LIMIT : Garder les 10 premiers
-- 5. SELECT : Retourner nom, prix, stock
UPDATE table SET colonne = nouvelle_valeur WHERE condition;
Explication :
UPDATE client -- 1. Table a modifier
SET email = 'nouveau@mail.com' -- 2. Colonne et nouvelle valeur
WHERE id = 1; -- 3. Quelle(s) ligne(s) modifier
-- Modifier plusieurs colonnes en meme temps
UPDATE client
SET
email = 'nouveau@mail.com',
telephone = '0123456789',
ville = 'Paris'
WHERE id = 1;
-- Les 3 colonnes sont modifiees pour id=1
On peut utiliser la valeur actuelle dans le calcul :
UPDATE produit
SET prix = prix * 1.10
WHERE id_categorie = 1;
-- ^
-- Utilise la valeur actuelle
-- Augmenter le stock de 10
UPDATE produit
SET stock = stock + 10
WHERE id = 5;
-- Reduire les prix de 20 euros
UPDATE produit
SET prix = prix - 20
WHERE prix > 100;
-- Changer le statut de TOUTES les commandes validees
UPDATE commande
SET statut = 'expediee'
WHERE statut = 'validee' AND date < '2024-12-01';
-- Toutes les lignes qui correspondent sont modifiees
-- ❌ ERREUR FATALE
UPDATE produit SET prix = 0;
-- TOUS les prix passent a 0 !
-- ✅ TOUJOURS mettre un WHERE
UPDATE produit SET prix = 0 WHERE id = 5;
-- Seulement le produit 5
SELECT avec le WHERE d'abordSELECT * par UPDATE<?php
// Modifier l'email d'un client
// ❌ DANGEREUX - Injection SQL
$email = $_POST['email'];
$id = $_GET['id'];
$sql = "UPDATE client SET email = '$email' WHERE id = $id";
// ✅ SECURISE - Prepared Statement
$email = $_POST['email'];
$id = $_GET['id'];
$stmt = $pdo->prepare("UPDATE client SET email = ? WHERE id = ?");
$stmt->execute([$email, $id]);
// Verifier le nombre de lignes modifiees
$nbModifies = $stmt->rowCount();
if ($nbModifies > 0) {
echo "Client modifie avec succes";
} else {
echo "Aucun client trouve avec cet ID";
}
?>
DELETE FROM table WHERE condition;
Explication :
DELETE FROM client -- 1. Table concernee
WHERE id = 2; -- 2. Quelle(s) ligne(s) supprimer
-- ⚠️ Pas de "SET" comme UPDATE
-- ⚠️ Pas de colonnes a specifier
-- On supprime la LIGNE ENTIERE
-- Supprimer un client specifique
DELETE FROM client WHERE id = 5;
-- Supprimer les commandes annulees de 2023
DELETE FROM commande
WHERE statut = 'annulee'
AND date < '2024-01-01';
-- Supprimer les produits sans stock
DELETE FROM produit WHERE stock = 0;
-- ❌ CATASTROPHE : Oubli du WHERE
DELETE FROM client;
-- TOUS LES CLIENTS SONT SUPPRIMES !
-- IRRÉVERSIBLE !
-- ✅ TOUJOURS mettre un WHERE
DELETE FROM client WHERE id = 5;
rm -rf * (équivalent de DELETE sans WHERE)-- Etape 1 : SELECT pour verifier
SELECT * FROM commande
WHERE statut = 'annulee' AND date < '2024-01-01';
-- Resultat : 3 lignes trouvees
-- -> Verifier que ce sont bien ces 3 lignes
-- Etape 2 : Remplacer SELECT par DELETE
DELETE FROM commande
WHERE statut = 'annulee' AND date < '2024-01-01';
-- Supprime exactement les 3 lignes verifiees
| Aspect | DELETE | TRUNCATE |
|---|---|---|
| Suppression | Ligne par ligne | Toute la table d'un coup |
| WHERE possible | ✅ Oui | ❌ Non |
| Vitesse | Lent | Très rapide |
| AUTO_INCREMENT | Conservé | Réinitialisé à 1 |
| Rollback | Possible (transaction) | Difficile |
-- DELETE : Supprime ligne par ligne
DELETE FROM produit WHERE stock = 0;
-- TRUNCATE : Vide TOUTE la table instantanement
TRUNCATE TABLE produit;
-- Equivalent a DELETE FROM produit (mais plus rapide)
-- ⚠️ ATTENTION : Supprime TOUT, pas de WHERE possible
<?php
// Supprimer un client
// ❌ DANGEREUX
$id = $_GET['id'];
$sql = "DELETE FROM client WHERE id = $id";
// ✅ SECURISE - Prepared Statement
$id = $_GET['id'];
// Etape 1 : Verifier d'abord
$stmt = $pdo->prepare("SELECT * FROM client WHERE id = ?");
$stmt->execute([$id]);
$client = $stmt->fetch();
if ($client) {
// Etape 2 : Confirmer avec l'utilisateur (JavaScript)
echo "Supprimer {$client['nom']} ?";
// Etape 3 : Supprimer si confirmation
$stmt = $pdo->prepare("DELETE FROM client WHERE id = ?");
$stmt->execute([$id]);
$nbSupprimes = $stmt->rowCount();
echo "$nbSupprimes client(s) supprime(s)";
} else {
echo "Client introuvable";
}
?>
// Toujours demander confirmation
if (confirm('Supprimer ce client ?')) {
// Envoyer la requete de suppression
window.location = 'delete.php?id=5';
}
| Opérateur | Description | Exemple |
|---|---|---|
= |
Égal | WHERE id = 5 |
!= ou <> |
Différent | WHERE statut != 'annule' |
< > <= >= |
Comparaison | WHERE prix >= 100 |
BETWEEN |
Entre deux valeurs | WHERE prix BETWEEN 10 AND 100 |
IN |
Dans une liste | WHERE id IN (1, 5, 10) |
LIKE |
Motif (% = n'importe quoi) | WHERE nom LIKE '%phone%' |
IS NULL |
Valeur nulle | WHERE telephone IS NULL |
AND |
ET logique | WHERE prix < 100 AND stock > 0 |
OR |
OU logique | WHERE ville = 'Paris' OR ville = 'Lyon' |
Relier les tables entre elles
Une jointure relie deux tables via une relation :
Résultat après jointure :
SELECT colonnes FROM table1 INNER JOIN table2 ON table1.cle = table2.cle;
Analogie : Comme une intersection de deux ensembles
-- Requete : Commandes avec noms des clients
SELECT
commande.id,
commande.total,
commande.date,
client.nom,
client.prenom
FROM commande
INNER JOIN client ON commande.id_client = client.id;
-- ^
-- Condition de jointure
Explication ligne par ligne :
SELECT -- 1. Colonnes a afficher
commande.id, -- De la table commande
client.nom -- De la table client
FROM commande -- 2. Table principale
INNER JOIN client -- 3. Table a joindre
ON commande.id_client = client.id; -- 4. Comment les relier
Les alias rendent le code plus court et lisible :
-- Sans alias (long)
SELECT
commande.id,
commande.total,
client.nom,
client.prenom
FROM commande
INNER JOIN client ON commande.id_client = client.id;
-- Avec alias (court)
SELECT
c.id,
c.total,
cl.nom,
cl.prenom
FROM commande c -- c = alias pour commande
INNER JOIN client cl ON c.id_client = cl.id;
-- ^ ^
-- Alias Utilise l'alias
c pour commande, cl pour client, p pour produit...
On peut ajouter des conditions et trier :
-- Commandes de plus de 50 euros avec nom du client
SELECT
c.id,
c.total,
c.date,
cl.nom,
cl.prenom
FROM commande c
INNER JOIN client cl ON c.id_client = cl.id
WHERE c.total > 50 -- Filtre APRES jointure
ORDER BY c.total DESC; -- Trie par montant
Ordre d'exécution :
Différence avec INNER JOIN :
-- Tous les clients, avec ou sans commandes
SELECT
client.id,
client.nom,
client.prenom,
commande.id AS commande_id,
commande.total
FROM client -- Table de GAUCHE
LEFT JOIN commande ON client.id = commande.id_client;
-- Tous les clients, meme sans commande
Résultat :
Durand apparaît avec NULL car pas de commande
Cas d'usage TRÈS utile : trouver ce qui manque
SELECT client.*
FROM client
LEFT JOIN commande ON client.id = commande.id_client
WHERE commande.id IS NULL;
-- ^
-- Si NULL = pas de commande
-- Resultat : Seulement les clients sans commande
+----+---------+---------+
| id | nom | prenom |
+----+---------+---------+
| 3 | Durand | Sophie |
+----+---------+---------+
SELECT produit.*
FROM produit
LEFT JOIN ligne_commande lc ON produit.id = lc.id_produit
WHERE lc.id_produit IS NULL;
-- Produits qui n'ont jamais ete commandes
-- Nombre de commandes par client (meme 0)
SELECT
client.nom,
COUNT(commande.id) AS nb_commandes,
COALESCE(SUM(commande.total), 0) AS total_depense
FROM client
LEFT JOIN commande ON client.id = commande.id_client
GROUP BY client.id;
-- Resultat :
-- Dupont | 2 | 149.49
-- Martin | 1 | 29.99
-- Durand | 0 | 0.00 <- INCLUS avec 0
-- Tous les produits, meme sans categorie
SELECT
produit.nom,
produit.prix,
categorie.nom AS categorie
FROM produit
LEFT JOIN categorie ON produit.id_categorie = categorie.id;
-- Commandes avec client ET produits
SELECT
cmd.id AS commande_id,
cmd.date,
cl.nom AS client_nom,
p.nom AS produit_nom,
lc.quantite,
lc.prix_unitaire
FROM commande cmd
INNER JOIN client cl ON cmd.id_client = cl.id
INNER JOIN ligne_commande lc ON cmd.id = lc.id_commande
INNER JOIN produit p ON lc.id_produit = p.id
WHERE cmd.id = 1;
-- Produits avec leur catégorie
SELECT
p.nom AS produit,
p.prix,
c.nom AS categorie
FROM produit p
INNER JOIN categorie c ON p.id_categorie = c.id
ORDER BY c.nom, p.nom;
| Fonction | Description | Exemple |
|---|---|---|
COUNT() |
Compter | COUNT(*) |
SUM() |
Somme | SUM(total) |
AVG() |
Moyenne | AVG(prix) |
MIN() |
Minimum | MIN(prix) |
MAX() |
Maximum | MAX(prix) |
-- Nombre de commandes par client
SELECT
client.nom,
COUNT(commande.id) AS nb_commandes,
SUM(commande.total) AS total_depense
FROM client
LEFT JOIN commande ON client.id = commande.id_client
GROUP BY client.id;
-- Prix moyen par catégorie
SELECT
categorie.nom,
COUNT(produit.id) AS nb_produits,
AVG(produit.prix) AS prix_moyen
FROM categorie
LEFT JOIN produit ON categorie.id = produit.id_categorie
GROUP BY categorie.id;
INSERT INTO : AjouterSELECT : LireUPDATE : ModifierDELETE : SupprimerINNER JOIN : Relier les tablesGROUP BY : Regrouper et compter🗄️ MCD → MLD → MPD → SQL = Maîtrise des BDD !