Les bases de données relationnelles sont au cœur de nombreuses applications web modernes, et les requêtes SQL permettent de manipuler ces données efficacement. L’une des fonctionnalités les plus puissantes est l’opération JOIN en SQL, qui permet de combiner des données de plusieurs tables. Dans ce tutoriel, nous allons vous détailler comment utiliser les JOIN en SQL avec PHP de manière simple et avec des exemples concrets.
Quand on débute avec une base de données, on a souvent l’impression que :
- une table = un type de données
- une requête = une table à la fois
Puis arrive le moment où l’on veut afficher :
- un client AVEC ses commandes
- un utilisateur AVEC ses articles
- un produit AVEC sa catégorie
Et là, une question simple surgit :
Comment récupérer des informations qui sont réparties dans plusieurs tables ?
C’est exactement le rôle de la requête JOIN en SQL.
- Ce qu’est une base de données relationnelle
- Pourquoi les tables sont séparées
- Ce que sont les clés primaires et clés étrangères
- Comment fonctionnent les différents types de JOIN
- Quand utiliser chaque jointure
Le tout avec :
- des exemples SQL clairs
- des cas concrets
- et une utilisation réelle de JOIN avec PHP
👉 Objectif : qu’à la fin de ce tutoriel, la requête JOIN soit maitrisée !
- Qu'est-ce qu'un JOIN en SQL ?
- Comprendre les bases d’une base de données relationnelle
- La clé primaire : l’identité unique d’une ligne
- La clé étrangère : le lien entre les tables
- La requête JOIN : relier les tables entre elles
- Les clés primaire et étrangère sont-elles obligatoire pour faire un JOIN ?
- Exemple Concret de JOIN en PHP
- Utilisation de INNER JOIN en SQL avec PHP
- Utilisation de LEFT JOIN en SQL avec PHP
- Utilisation de RIGHT JOIN en SQL avec PHP
- Utilisation de FULL JOIN en SQL avec PHP
- FAQ – Les questions les plus fréquentes sur les JOIN en SQL
- Faut-il obligatoirement une clé primaire et une clé étrangère pour faire un JOIN ?
- Quelle est la différence entre INNER JOIN et LEFT JOIN ?
- Pourquoi j’obtiens des valeurs NULL avec un LEFT JOIN ?
- Pourquoi mon LEFT JOIN se comporte comme un INNER JOIN ?
- Le JOIN ralentit-il les performances d’une base de données ?
- Un schéma vaut mieux que mille mots …
Qu’est-ce qu’un JOIN en SQL ?
Un JOIN est une opération SQL qui permet de combiner des lignes de deux ou plusieurs tables en utilisant une colonne commune entre elles. Il existe plusieurs types de JOIN :
- INNER JOIN : Les lignes qui existent dans les deux tables.
- LEFT JOIN (ou LEFT OUTER JOIN) : Renvoie tous les enregistrements de la table de gauche et les enregistrements correspondants de la table de droite. Si aucune correspondance n’est trouvée, les résultats de la table de droite seront NULL.
- RIGHT JOIN (ou RIGHT OUTER JOIN) : Renvoie tous les enregistrements de la table de droite et les enregistrements correspondants de la table de gauche. Si aucune correspondance n’est trouvée, les résultats de la table de gauche seront NULL.
- FULL JOIN (ou FULL OUTER JOIN) : Renvoie tous les enregistrements lorsqu’il y a une correspondance dans une des tables. Si aucune correspondance n’est trouvée, les résultats seront NULL de la table non correspondante.

Comprendre les bases d’une base de données relationnelle
Mais, avant d’aller plus loin avec JOIN, il faut comprendre pourquoi ils existent.
Pourquoi séparer les données en plusieurs tables ?
Imaginons une application simple avec :
- des clients
- des commandes
Une mauvaise idée serait de tout mettre dans une seule table :
clients_commandes
- nom_client
- email_client
- adresse_client
- date_commande
- montant_commande
Pourquoi c’est une mauvaise idée ?
- le nom du client serait répété à chaque commande
- l’adresse serait dupliquée inutilement
- la base deviendrait lourde et incohérente
C’est pour éviter ça qu’on utilise une base de données relationnelle.
Principe d’une base relationnelle
Dans une base relationnelle :
- chaque table représente une entité
- les relations entre les tables sont faites via des identifiants
On va donc séparer les données :
Table clients
- id
- nom
Table commandes
- id
- client_id
- date_commande
- montant
Les données sont propres, organisées, et surtout liées intelligemment. Mais alors… Comment relier une commande à son client ?
👉 C’est ici que les clés entrent en jeu.
La clé primaire : l’identité unique d’une ligne
Une clé primaire est un champ qui permet d’identifier de manière unique chaque ligne d’une table. Très souvent, il s’agit d’un champ id auto-incrémenté.
CREATE TABLE clients (
id INT PRIMARY KEY AUTO_INCREMENT,
nom VARCHAR(100),
email VARCHAR(150)
);
Dans cette table :
- chaque client possède un
idunique - deux clients ne peuvent jamais avoir le même
id
La clé primaire est indispensable :
- pour identifier une ligne
- pour créer des relations avec d’autres tables
Pourquoi ne pas utiliser l’email comme clé primaire ? C’est une question fréquente … Même si un email est unique :
- il peut changer
- il est plus lourd à manipuler
- il n’est pas optimisé pour les relations
👉 Une clé primaire doit être :
- simple
- stable
- courte
D’où l’utilisation quasi systématique d’un id.
La clé étrangère : le lien entre les tables
Qu’est-ce qu’une clé étrangère ? Une clé étrangère est un champ qui fait référence à la clé primaire d’une autre table. Il faut la déclarer explicitement avec FOREIGN KEY.
CREATE TABLE commandes (
id INT PRIMARY KEY AUTO_INCREMENT,
client_id INT,
date_commande DATE,
montant DECIMAL(10,2),
CONSTRAINT fk_commandes_clients
FOREIGN KEY (client_id)
REFERENCES clients(id)
);
Ici :
client_idfait référence àclients.id- chaque commande est liée à un client
On peut le voir comme :
“Cette commande appartient à ce client.”
Relation entre tables : un exemple concret
Imaginons ces données :
clients
- id = 1 → Jean
- id = 2 → Marie
commandes
- id = 101 → client_id = 1
- id = 102 → client_id = 1
- id = 103 → client_id = 2
Sans JOIN, ces données sont séparées. Avec JOIN, on peut dire :
“Donne-moi les commandes avec le nom du client.”
Et c’est exactement ce que fait une jointure SQL.
👉 Pour aller plus loin : Index SQL / MySQL et Clé SQL / MySQL
La requête JOIN : relier les tables entre elles
Définition simple d’une jointure SQL : Une requête JOIN permet de :
- combiner des lignes de plusieurs tables
- en fonction d’un lien commun (clé primaire ↔ clé étrangère)
Syntaxe générale :
SELECT colonnes
FROM table1
JOIN table2
ON condition
La condition indique comment les tables sont reliées.
Les clés primaire et étrangère sont-elles obligatoire pour faire un JOIN ?
- Non, les clés primaires et étrangères ne sont PAS obligatoires pour faire un JOIN.
- Oui, elles sont fortement recommandées dans une vraie base de données.
Et maintenant, on explique calmement le pourquoi.
Ce que SQL demande réellement pour faire un JOIN
Pour qu’un JOIN fonctionne, SQL a besoin d’une seule chose :
Une colonne commune entre les tables, avec des valeurs comparables.
Par exemple :
SELECT *
FROM clients
JOIN commandes
ON clients.id = commandes.client_id;
Ici :
- SQL se moque totalement de savoir si
idest une clé primaire - SQL se moque de savoir si
client_idest une clé étrangère - il compare juste des valeurs
👉 Tant que les données correspondent, le JOIN fonctionne.
Exemple sans clé primaire ni clé étrangère :
CREATE TABLE clients (
identifiant INT,
nom VARCHAR(100)
);
CREATE TABLE commandes (
client INT,
montant DECIMAL(10,2)
);
JOIN possible :
SELECT *
FROM clients
JOIN commandes
ON clients.identifiant = commandes.client;
✔️ Ça marche
❌ Mais c’est dangereux
Alors à quoi servent vraiment les clés ?
👉 Une clé primaire garantit :
- une valeur unique
- une ligne identifiable sans ambiguïté
Sans clé primaire :
- doublons possibles
- résultats incohérents
- JOIN imprévisibles
👉 Une clé étrangère garantit :
- que la relation est valide
- que les données restent cohérentes
Sans clé étrangère :
- commandes sans client
- données orphelines
- bugs silencieux
| Élément | Obligatoire pour JOIN ? | Utile ? |
|---|---|---|
| Colonne commune | ✅ Oui | Indispensable |
| Clé primaire | ❌ Non | Très important |
| Clé étrangère | ❌ Non | Très important |
Pourquoi on insiste autant dessus dans les cours
Parce qu’un JOIN peut fonctionner aujourd’hui mais casser la base demain.
Les clés ne servent pas à JOIN, elles servent à protéger la base
Un JOIN compare des valeurs, pas des clés.
Les clés servent à garantir que ces valeurs restent fiables.
Pour résumé :
- On peut faire des JOIN sans aucune clé
- On ne devrait jamais le faire en production
- Les clés ne sont pas là pour SQL, elles sont là pour protéger vos données
Exemple Concret de JOIN en PHP
Imaginons une base de données simple pour une boutique en ligne qui possèdent deux tables : clients qui contient les informations des clients et commandes qui contient les informations des commandes passées par les clients.
Des formations informatique pour tous !
Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…
Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.
Découvrez mes formations Qui suis-je ?Voici les structures simplifiées de ces tables :
Table clients
| id_client | nom |
|---|---|
| 1 | Alice |
| 2 | Jean |
| 3 | Michel |
Table commandes
| id_commande | id_client | produit |
|---|---|---|
| 1 | 1 | Ordinateur |
| 2 | 1 | Souris |
| 3 | 2 | Clavier |
Utilisation de INNER JOIN en SQL avec PHP
INNER JOIN est la jointure la plus utilisée. Le INNER JOIN retourne uniquement :
- les lignes qui existent dans les deux tables
Autrement dit :
Si la relation n’existe pas, la ligne n’apparaît pas.
SELECT clients.nom, commandes.produit
FROM clients
INNER JOIN commandes
ON clients.id_client = commandes.client_id;
Résultat :
- uniquement les clients qui ont au moins une commande (Alice et Jean)
- chaque commande est affichée avec le nom du client
Si un client n’a jamais commandé :
- il n’apparaîtra pas dans le résultat
INNER JOIN est très important parce que c’est le JOIN par défaut. Il correspond à la majorité des besoins réels, il est performant et il évite les données inutiles.
Quand on dit simplement JOIN en SQL, cela signifie INNER JOIN.
INNER JOIN avec PHP et PDO
$sql = "
SELECT clients.nom, commandes.produit
FROM clients
INNER JOIN commandes
ON clients.id_client = commandes.client_id
";
$stmt = $pdo->query($sql);
$resultats = $stmt->fetchAll(PDO::FETCH_ASSOC);
Chaque ligne contiendra :
- le nom du client
- le produit de la commande
Les cas d’usage typique du INNER JOIN :
- afficher des commandes avec leurs clients
- afficher des articles avec leurs auteurs
- afficher des produits avec leurs catégories
- etc..
Dès qu’une relation est obligatoire, INNER JOIN est le bon choix.
Le code entier :
// Connexion à la base de données
$host = 'localhost';
$db = 'ma_boutique';
$user = 'root';
$pass = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die("Erreur de connexion : " . $e->getMessage());
}
// Requête SQL avec INNER JOIN
$sql = "
SELECT clients.nom, commandes.produit
FROM clients
INNER JOIN commandes ON clients.id_client = commandes.id_client
";
try {
$stmt = $pdo->prepare($sql);
$stmt->execute();
$resultats = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($resultats as $ligne) {
echo "Client: " . $ligne['nom'] . " - Produit: " . $ligne['produit'] . "
";
}
} catch (PDOException $e) {
echo "Erreur de requête : " . $e->getMessage();
}
Explication du Code :
- Connexion à la base de données : Utilisation de PDO pour se connecter à la base de données MySQL.
- Requête SQL : La requête sélectionne le nom du client et le produit commandé en utilisant un
INNER JOIN. Cette opération combine les tables clients et commandes sur la colonneid_clientcommune. - Exécution de la requête : Préparation et exécution de la requête avec PDO.
- Affichage des résultats : Parcours des résultats et affichage des informations.
SELECT clients.nom, commandes.produit
FROM clients
INNER JOIN commandes ON clients.id_client = commandes.id_client;
SELECT clients.nom, commandes.produit :
Nous sélectionnons la colonne nom de la table clients. Nous sélectionnons également la colonne produit de la table commandes.
FROM clients : Cette clause spécifie la table principale à partir de laquelle les données seront sélectionnées.
INNER JOIN commandes : Ce type de jointure retourne uniquement les enregistrements qui ont des valeurs correspondantes dans les deux tables. La table que nous voulons joindre à la table principale clients.
ON clients.id_client = commandes.id_client :
Cette clause spécifie la condition de jointure, c’est-à-dire la colonne sur laquelle les deux tables seront liées. La condition de jointure est que la colonne id_client de la table clients doit correspondre à la colonne id_client de la table commandes.
L’INNER JOIN combine les lignes des deux tables uniquement lorsque la condition spécifiée est remplie. Dans cet exemple, la condition est que la valeur de id_client dans la table clients doit être égale à la valeur de id_client dans la table commandes. Seules les lignes pour lesquelles cette condition est vraie seront incluses dans le résultat final.
Résultat
Alice a deux commandes (Ordinateur et Souris), donc elle apparaît deux fois dans le résultat, une fois pour chaque commande. Jean a une commande (Clavier), donc il apparaît une fois dans le résultat. En revanche, Michel n’a pas de commandes, donc il n’apparaît pas dans le résultat.
Utilisation de LEFT JOIN en SQL avec PHP
Reprenons une situation très courante.
Vous avez :
- des clients
- des commandes
Et vous voulez afficher :
- tous les clients
- avec leurs commandes s’ils en ont
- même ceux qui n’ont encore rien commandé
Avec un INNER JOIN, ces clients invisibles disparaissent. C’est précisément pour ce cas que le LEFT JOIN existe.
Un LEFT JOIN retourne :
- toutes les lignes de la table de gauche
- et les données correspondantes de la table de droite
- même s’il n’y a aucune correspondance
Voici un exemple de LEFT JOIN pour inclure tous les clients, même ceux qui n’ont pas passé de commande :
SELECT clients.nom, commandes.produit
FROM clients
LEFT JOIN commandes ON clients.id_client = commandes.id_client
Cette requête LEFT JOIN sert à combiner les tables clients et commandes. Cette opération sélectionne le nom des clients de la table clients et les produits associés de la table commandes, liant les deux tables sur la colonne commune id_client.
Le LEFT JOIN inclut toutes les lignes de la table clients, même si certaines n’ont pas de correspondance dans la table commandes. Ainsi, si un client n’a pas passé de commande, son nom apparaîtra toujours dans les résultats, mais la colonne produit sera remplie avec une valeur NULL. Par exemple, un client nommé Michel, qui n’a pas passé de commande, sera listé avec une valeur NULL pour le produit, tandis que des clients comme Alice et Jean, ayant passé des commandes, apparaîtront avec les produits qu’ils ont achetés.
Utilisation de RIGHT JOIN en SQL avec PHP
Le RIGHT JOIN est l’exact inverse du LEFT JOIN. Il retourne :
- toutes les lignes de la table de droite
- même si aucune correspondance n’existe dans la table de gauche
RIGHT JOIN est rarement utilisé car dans la pratique :
- tout RIGHT JOIN peut être réécrit en LEFT JOIN
- il suffit d’inverser l’ordre des tables
Si vous débutez :
- maîtrisez INNER JOIN
- maîtrisez LEFT JOIN
- comprenez RIGHT JOIN, mais ne vous forcez pas à l’utiliser
RIGHT JOIN retourne donc tous les enregistrements de la table de droite (commandes) et les enregistrements correspondants de la table de gauche (clients). Si aucune correspondance n’est trouvée, les résultats de la table de gauche seront NULL.
SELECT clients.nom, commandes.produit
FROM clients
RIGHT JOIN commandes ON clients.id_client = commandes.id_client
Dans cet exemple, nous allons obtenir une liste de tous les produits commandés, même si certains clients n’ont pas de nom associé (dans le cas où le client aurait été supprimé de la table clients).
Utilisation de FULL JOIN en SQL avec PHP
Un FULL JOIN retourne :
- toutes les lignes de la table de gauche
- toutes les lignes de la table de droite
- qu’il y ait correspondance ou non
C’est la jointure la plus “large”.
FULL JOIN combine les résultats de LEFT JOIN et RIGHT JOIN. MySQL ne supporte pas directement FULL JOIN, mais on peut le simuler en combinant LEFT JOIN et RIGHT JOIN avec une union.
SELECT clients.nom, commandes.produit
FROM clients
LEFT JOIN commandes ON clients.id_client = commandes.id_client
UNION
SELECT clients.nom, commandes.produit
FROM clients
RIGHT JOIN commandes ON clients.id_client = commandes.id_client
La requête SQL combine un LEFT JOIN et un RIGHT JOIN avec une union pour simuler un FULL JOIN.
La première partie utilise un LEFT JOIN pour sélectionner tous les clients et leurs commandes, incluant les clients sans commande, qui auront une valeur NULL pour les produits.
La seconde partie utilise un RIGHT JOIN pour inclure toutes les commandes, même celles sans clients, où les noms des clients seront NULL si aucune correspondance n’est trouvée.
L’union des résultats des deux jointures garantit que toutes les lignes de chaque table sont incluses, simulant ainsi un FULL JOIN.
FAQ – Les questions les plus fréquentes sur les JOIN en SQL
Faut-il obligatoirement une clé primaire et une clé étrangère pour faire un JOIN ?
Non, ce n’est pas obligatoire pour que le JOIN fonctionne.
Un JOIN compare simplement des valeurs entre deux colonnes. Tant que ces valeurs correspondent, la jointure est possible, même si aucune clé n’est déclarée au niveau SQL.
En revanche, les clés primaires et étrangères sont fortement recommandées. Elles garantissent la cohérence des données et évitent les erreurs invisibles, comme des commandes liées à des clients inexistants.
En résumé : les JOIN fonctionnent sans clés, mais les bases solides ne s’en passent pas.
Quelle est la différence entre INNER JOIN et LEFT JOIN ?
La différence tient à ce que l’on veut afficher quand il n’y a pas de correspondance.
Un INNER JOIN n’affiche que les lignes qui existent dans les deux tables.
Si la relation n’existe pas, la ligne est ignorée.
Un LEFT JOIN affiche toutes les lignes de la table de gauche, même s’il n’y a aucune correspondance dans la table de droite.
Dans ce cas, les colonnes de la table de droite contiennent NULL.
On utilise donc :
- LEFT JOIN quand la relation est facultative
- INNER JOIN quand la relation est obligatoire
Pourquoi j’obtiens des valeurs NULL avec un LEFT JOIN ?
Les valeurs NULL apparaissent lorsque aucune correspondance n’est trouvée dans la table jointe.
- Cela ne signifie pas une erreur.
- Cela signifie simplement que la relation n’existe pas encore.
Par exemple :
- un client sans commande
- un utilisateur sans article
- un produit jamais vendu
Le NULL indique une absence de donnée, pas une donnée vide ou égale à zéro.
Pourquoi mon LEFT JOIN se comporte comme un INNER JOIN ?
C’est une erreur très fréquente. La cause la plus courante est l’utilisation d’une condition dans le WHERE sur la table jointe. Dans ce cas, SQL filtre les résultats après la jointure, ce qui annule l’effet du LEFT JOIN.
Pour conserver le comportement du LEFT JOIN, les conditions liées à la jointure doivent être placées dans le ON, et non dans le WHERE.
Le JOIN ralentit-il les performances d’une base de données ?
Non, un JOIN bien conçu n’est pas un problème de performance.
Les JOIN sont faits pour être utilisés, et les bases de données relationnelles sont optimisées pour cela. Les vrais problèmes viennent généralement :
- de tables mal indexées
- de colonnes non adaptées aux relations
- ou de requêtes mal construites
Avec des clés primaires, des clés étrangères et des index correctement définis, les JOIN restent performants, même sur des bases volumineuses.
Un schéma vaut mieux que mille mots …

Les JOIN en SQL sont essentiels pour travailler avec des bases de données relationnelles, et leur utilisation avec PHP est courante dans le développement d’applications web. En comprenant et en maîtrisant les différents types de JOIN (INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN), vous pouvez créer des requêtes puissantes pour extraire et manipuler des données efficacement. Utilisez ce tutoriel comme référence pour vos futurs projets et expérimentez avec différentes requêtes pour mieux comprendre leur fonctionnement.

Fondateur de l’agence Créa-troyes, affiliée France Num
Intervenant en Freelance.
Contactez-moi
