logo oujood
🔍

Les jointures SQL avec Node.js et MySQL

INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, CROSS JOIN — comment les utiliser et lesquels choisir selon votre besoin.

OUJOOD.COM

Quand on travaille avec plusieurs tables MySQL, les jointures SQL deviennent vite indispensables. Ce tutoriel couvre les cinq types de jointures — INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN simulé et CROSS JOIN — avec des exemples concrets exécutés depuis Node.js. On commence avec le module classique mysql, puis on bascule sur mysql2 et ses Promises pour un code plus moderne.

Créer les tables de test

Pour tous les exemples qui suivent, on utilise deux tables simples : members (membres) et committees (comités). Certains noms apparaissent dans les deux tables, d'autres dans une seule — ce qui rend les différences entre les jointures bien visibles.

  📋 Copier le code

CREATE TABLE members (
   member_id INT AUTO_INCREMENT,
   name VARCHAR(100),
   PRIMARY KEY (member_id)
);

INSERT INTO members(name)
VALUES('John'), ('Jane'), ('Mary'), ('David'), ('Amelia');
  • CREATE TABLE members : crée la table avec deux colonnes, member_id et name.
  • AUTO_INCREMENT : chaque nouveau membre reçoit automatiquement un identifiant unique.
  • INSERT INTO members : insère cinq membres d'un coup avec une seule requête.

  📋 Copier le code

CREATE TABLE committees (
   committee_id INT AUTO_INCREMENT,
   name VARCHAR(100),
   PRIMARY KEY (committee_id)
);

INSERT INTO committees(name)
VALUES('Joe'), ('Sarah'), ('Amelia'), ('David');
  • CREATE TABLE committees : même structure que members, avec committee_id à la place de member_id.
  • Seuls Amelia et David sont présents dans les deux tables — les autres noms sont exclusifs à l'une ou l'autre.

LEFT JOIN : tous les membres, avec ou sans comité

Le LEFT JOIN retourne toutes les lignes de la table de gauche (members), plus les correspondances trouvées dans la table de droite (committees). Si un membre n'a pas de comité associé, ses colonnes côté committees affichent NULL.

Requête SQL

  📋 Copier le code

SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
LEFT JOIN committees c ON c.name = m.name;
  • FROM members m : la table de gauche, qui pilote les résultats — toutes ses lignes seront présentes.
  • LEFT JOIN committees c ON c.name = m.name : pour chaque membre, MySQL cherche un comité portant le même nom. S'il n'en trouve pas, les colonnes de committees valent NULL.

Avec Node.js — module mysql

Voici comment exécuter ce LEFT JOIN depuis Node.js avec le module mysql classique (callback-based).

  📋 Copier le code

const mysql = require('mysql');

// Paramètres de connexion à votre base MySQL
const con = mysql.createConnection({
   host: "localhost",
   user: "root",
   password: "votre_mot_de_passe",
   database: "votre_base_de_donnees"
});

const qry = `
SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
LEFT JOIN committees c ON c.name = m.name;
`;

con.connect(function(err) {
   if (err) throw err;
   con.query(qry, function (err, results) {
      if (err) throw err;
      results.forEach((row) => {
         console.log(JSON.stringify(row));
      });
   });
   con.end();
});
  • require('mysql') : importe le module de connexion MySQL pour Node.js.
  • createConnection : définit les paramètres de connexion (hôte, utilisateur, mot de passe, base).
  • con.query : envoie la requête et traite les résultats dans le callback.

Résultat attendu

member_idmembercommittee_idcommittee
1JohnNULLNULL
2JaneNULLNULL
3MaryNULLNULL
4David4David
5Amelia3Amelia

John, Jane et Mary n'apparaissent pas dans committees, donc leurs colonnes côté comité sont à NULL. David et Amelia existent dans les deux tables — leurs lignes sont complètes.

LEFT JOIN avec mysql2 et async/await

Le module mysql2 est l'évolution naturelle de mysql. Sa compatibilité avec les Promises permet d'écrire un code asynchrone plus lisible, sans callbacks imbriqués. Pour l'installer :

  📋 Copier le code

npm install mysql2

Ensuite, le même LEFT JOIN s'écrit ainsi avec mysql2/promise :

  📋 Copier le code

const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "votre_mot_de_passe",
        database: "votre_base_de_donnees"
    });

    try {
        // execute() prépare la requête avant de l'envoyer — plus sûr que query()
        const [rows] = await connection.execute(`
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            LEFT JOIN committees c ON c.name = m.name;
        `);

        rows.forEach((row) => {
            console.log(JSON.stringify(row));
        });
    } catch (error) {
        console.error("Erreur :", error);
    } finally {
        // finally garantit que la connexion se ferme même en cas d'erreur
        await connection.end();
    }
})();
  • require('mysql2/promise') : importe la version Promise du module.
  • connection.execute : prépare et exécute la requête en une seule étape, plus sûr que query() contre les injections SQL.
  • try-catch-finally : la connexion se ferme dans le bloc finally, que la requête ait réussi ou échoué.

RIGHT JOIN : tous les comités, avec ou sans membre

Le RIGHT JOIN inverse la logique : cette fois, c'est la table de droite (committees) qui pilote les résultats. Toutes ses lignes apparaissent dans la sortie, même si elles n'ont pas de correspondance dans members.

Requête SQL

  📋 Copier le code

SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
RIGHT JOIN committees c ON c.name = m.name;
  • RIGHT JOIN committees c : inclut toutes les lignes de committees, même celles sans membre associé.
  • Là où aucun membre ne correspond, les colonnes de members valent NULL.

Avec Node.js et mysql2

  📋 Copier le code

const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "votre_mot_de_passe",
        database: "votre_base_de_donnees"
    });

    try {
        const [rows] = await connection.execute(`
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            RIGHT JOIN committees c ON c.name = m.name;
        `);

        rows.forEach((row) => {
            console.log(JSON.stringify(row));
        });
    } catch (error) {
        console.error("Erreur :", error);
    } finally {
        await connection.end();
    }
})();

Résultat attendu

member_idmembercommittee_idcommittee
NULLNULL1Joe
NULLNULL2Sarah
5Amelia3Amelia
4David4David

Joe et Sarah n'existent que dans committees — leurs colonnes côté membres restent à NULL. Amelia et David sont dans les deux tables et s'affichent complets.

INNER JOIN : uniquement les correspondances

L'INNER JOIN est le plus restrictif des quatre : il ne retourne que les lignes qui ont une correspondance dans les deux tables simultanément. Pas de NULL, pas de lignes orphelines.

Requête SQL

  📋 Copier le code

SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
INNER JOIN committees c ON c.name = m.name;
  • INNER JOIN committees c ON c.name = m.name : seuls les noms présents dans les deux tables passent le filtre.

Avec Node.js et mysql2

  📋 Copier le code

const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "votre_mot_de_passe",
        database: "votre_base_de_donnees"
    });

    try {
        const [rows] = await connection.execute(`
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            INNER JOIN committees c ON c.name = m.name;
        `);

        rows.forEach((row) => {
            console.log(JSON.stringify(row));
        });
    } catch (error) {
        console.error("Erreur :", error);
    } finally {
        await connection.end();
    }
})();

Résultat attendu

member_idmembercommittee_idcommittee
4David4David
5Amelia3Amelia

Deux lignes seulement — David et Amelia — parce que ce sont les seuls noms communs aux deux tables.

FULL OUTER JOIN simulé : toutes les lignes, des deux côtés

MySQL ne dispose pas d'un mot-clé FULL OUTER JOIN natif. On le simule en combinant un LEFT JOIN et un RIGHT JOIN via UNION, ce qui déduplique les lignes communes et conserve toutes les lignes orphelines des deux tables.

Requête SQL

  📋 Copier le code

SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
LEFT JOIN committees c ON c.name = m.name
UNION
SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
RIGHT JOIN committees c ON c.name = m.name;
  • La première SELECT (LEFT JOIN) retourne tous les membres, avec ou sans comité.
  • La seconde SELECT (RIGHT JOIN) retourne tous les comités, avec ou sans membre.
  • UNION fusionne les deux résultats en supprimant les doublons automatiquement.

Avec Node.js et mysql2

  📋 Copier le code

const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "votre_mot_de_passe",
        database: "votre_base_de_donnees"
    });

    try {
        const [rows] = await connection.execute(`
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            LEFT JOIN committees c ON c.name = m.name
            UNION
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            RIGHT JOIN committees c ON c.name = m.name;
        `);

        rows.forEach((row) => {
            console.log(JSON.stringify(row));
        });
    } catch (error) {
        console.error("Erreur :", error);
    } finally {
        await connection.end();
    }
})();

Résultat attendu

member_idmembercommittee_idcommittee
1JohnNULLNULL
2JaneNULLNULL
3MaryNULLNULL
4David4David
5Amelia3Amelia
NULLNULL1Joe
NULLNULL2Sarah

Sept lignes en tout : les cinq membres (dont trois sans comité) et les deux comités (Joe, Sarah) qui n'ont pas de membre associé.

CROSS JOIN : toutes les combinaisons possibles

Le CROSS JOIN produit le produit cartésien des deux tables — chaque ligne de members est combinée avec chaque ligne de committees. Avec 5 membres et 4 comités, on obtient 20 lignes. C'est rarement ce qu'on veut en production, mais utile pour générer des matrices ou tester des scénarios exhaustifs.

Requête SQL

  📋 Copier le code

SELECT
   m.member_id,
   m.name AS member,
   c.committee_id,
   c.name AS committee
FROM
   members m
CROSS JOIN committees c;
  • CROSS JOIN : pas de condition ON — toutes les associations membre × comité sont générées.

Avec Node.js et mysql2

  📋 Copier le code

const mysql = require('mysql2/promise');

(async () => {
    const connection = await mysql.createConnection({
        host: "localhost",
        user: "root",
        password: "votre_mot_de_passe",
        database: "votre_base_de_donnees"
    });

    try {
        const [rows] = await connection.execute(`
            SELECT
                m.member_id,
                m.name AS member,
                c.committee_id,
                c.name AS committee
            FROM
                members m
            CROSS JOIN committees c;
        `);

        rows.forEach((row) => {
            console.log(JSON.stringify(row));
        });
    } catch (error) {
        console.error("Erreur :", error);
    } finally {
        await connection.end();
    }
})();

Extrait du résultat (20 lignes au total)

member_idmembercommittee_idcommittee
1John1Joe
1John2Sarah
1John3Amelia
1John4David

Quelle jointure utiliser et dans quel cas ?

Voici un tableau récapitulatif pour choisir rapidement la bonne jointure selon votre besoin.

Jointure Ce qu'elle retourne Cas d'usage typique
INNER JOIN Uniquement les lignes présentes dans les deux tables Lister les membres qui font partie d'un comité — sans lignes incomplètes
LEFT JOIN Toutes les lignes de gauche + correspondances de droite (NULL si absent) Lister tous les membres, y compris ceux sans comité
RIGHT JOIN Toutes les lignes de droite + correspondances de gauche (NULL si absent) Lister tous les comités, même ceux sans membres inscrits
FULL OUTER JOIN (simulé) Toutes les lignes des deux tables, correspondances ou non Obtenir une vue complète : membres sans comité et comités sans membres
CROSS JOIN Toutes les combinaisons possibles entre les deux tables Générer une matrice exhaustive — rarement utilisé en production

👉 Retrouvez d'autres tutoriels Node.js ici : Tutoriels Node.js

Par carabde | Mis à jour le 13 mai 2026