Leçon 7 / 8
Leçon 07 · Partie 2 — Modifier les données
JOIN — Relier des tables
Pourquoi plusieurs tables ?
Imagine une boutique en ligne. Tu as des utilisateurs et des commandes. Mauvaise idée de tout mettre dans une seule table :
-- Mauvaise approche : tout dans une table
+----+--------+------------------+----------+---------+
| id | nom | email | commande | montant |
+----+--------+------------------+----------+---------+
| 1 | Alice | alice@ex.com | Livre | 15.00 |
| 2 | Alice | alice@ex.com | Stylo | 3.50 |
| 3 | Alice | alice@ex.com | Cahier | 5.00 |
+----+--------+------------------+----------+---------+
-- Problème : email d'Alice répété 3 fois → redondance
La bonne approche : deux tables séparées. On les lie avec une clé étrangère. Une clé étrangère, c'est une colonne qui contient l'ID d'un enregistrement dans une autre table.
-- Table utilisateurs
CREATE TABLE utilisateurs (
id INT AUTO_INCREMENT PRIMARY KEY,
nom VARCHAR(100),
email VARCHAR(150)
);
-- Table commandes (liée à utilisateurs)
CREATE TABLE commandes (
id INT AUTO_INCREMENT PRIMARY KEY,
utilisateur_id INT NOT NULL, -- clé étrangère
produit VARCHAR(200),
montant DECIMAL(10,2),
date_commande DATETIME DEFAULT CURRENT_TIMESTAMP
);
INNER JOIN : relier les tables
INNER JOIN combine deux tables. Il retourne seulement les lignes qui ont une correspondance dans les deux. Pense à l'intersection de deux ensembles.
-- Toutes les commandes avec le nom et l'email du client
SELECT
u.nom,
u.email,
c.produit,
c.montant
FROM commandes c
INNER JOIN utilisateurs u
ON c.utilisateur_id = u.id;
// Résultat
+--------+-------------+---------+---------+
| nom | email | produit | montant |
+--------+-------------+---------+---------+
| Alice | alice@ex... | Livre | 15.00 |
| Alice | alice@ex... | Stylo | 3.50 |
| Bob | bob@ex... | Cahier | 5.00 |
+--------+-------------+---------+---------+
LEFT JOIN : inclure les lignes sans correspondance
-- Tous les utilisateurs, MÊME ceux sans commande
SELECT
u.nom,
COUNT(c.id) AS nb_commandes,
COALESCE(SUM(c.montant), 0) AS total
FROM utilisateurs u
LEFT JOIN commandes c
ON u.id = c.utilisateur_id
GROUP BY u.id, u.nom
ORDER BY total DESC;
JOIN avec PDO
require_once 'connexion.php';
$utilisateur_id = 1;
$stmt = $pdo->prepare("
SELECT u.nom, c.produit, c.montant, c.date_commande
FROM commandes c
INNER JOIN utilisateurs u ON c.utilisateur_id = u.id
WHERE u.id = :uid
ORDER BY c.date_commande DESC
");
$stmt->execute([':uid' => $utilisateur_id]);
$commandes = $stmt->fetchAll(PDO::FETCH_ASSOC);
// À retenir
- Clé étrangère = colonne qui fait référence à l'ID d'une autre table
- INNER JOIN = seulement les lignes avec correspondance dans les deux tables
- LEFT JOIN = toutes les lignes de la table gauche, même sans correspondance
- Utiliser des alias de table (u, c) pour les requêtes lisibles
- GROUP BY pour agréger des données (COUNT, SUM, AVG)
- Ne jamais dupliquer une donnée — une info = une seule fois dans la BDD