682 tutoriels en ligne

Créa-blog

#100JoursPourCoder
Projet Créa-code | Formation Créa-troyes

Ressources pour développeur web

Théme de la semaine : WebDesign

La requête JOIN en SQL avec PHP pour une BDD relationnelle

Temps de lecture estimé : 9 minutes
Accueil PHP 8 La requête JOIN en SQL avec PHP pour une BDD relationnelle

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 ?

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.
Les types SQL de JOIN en PHP

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
  • email

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 id unique
  • 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_id fait 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 id est une clé primaire
  • SQL se moque de savoir si client_id est 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émentObligatoire pour JOIN ?Utile ?
Colonne commune✅ OuiIndispensable
Clé primaire❌ NonTrès important
Clé étrangère❌ NonTrè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.

Formation web et informatique - Alban Guillier - Formateur

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_clientnom
1Alice
2Jean
3Michel

Table commandes

id_commandeid_clientproduit
11Ordinateur
21Souris
32Clavier

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 colonne id_client commune.
  • 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 …

SQL Join en PHP

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.