Qui a passé la commande 38 ?
Un JOIN relie deux tables d'une base de données grâce à une clé étrangère, pour afficher ensemble des informations rangées à deux endroits.
Il te permet de voir le nom du client à côté de sa commande, sans jamais recopier ce nom dans la table des commandes.
À la fin de cette leçon
Remarque
Je peux relier deux tables avec un JOIN.
Mots clés
| Mot | Ce que ça veut dire | Exemple |
|---|---|---|
| Clé étrangère | une colonne qui garde le numéro d'une ligne d'une autre table | customer_id |
| Jointure | la liaison de deux tables dans une requête | JOIN |
| Condition de jointure | le test qui dit quelles lignes vont ensemble | ON c.id = o.customer_id |
| Alias de table | un nom court donné à une table dans une requête | customers c |
| LEFT JOIN | une jointure qui garde aussi les lignes sans correspondance | |
| Produit cartésien | toutes les combinaisons de lignes de deux tables |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Une clé étrangère désigne une autre table
Une commande de la boutique n'écrit pas le nom du client. Elle garde son numéro, dans la colonne customer_id.
Cette colonne est une clé étrangère : elle désigne la clé primaire d'une autre table. Le nom du client est rangé une seule fois, dans customers. La base refuse un numéro de client qui n'existe pas.
Avant de commencer
Remarque
Appuie sur Start the lab dans la barre en haut et attends que la machine soit prête. Les deux Runs suivants servent à te connecter. Le deuxième crée un alias : un nom court, sql, pour une longue commande.
Accepter le certificat du serveur
printf '[client]\nssl-verify-server-cert=0\n' > ~/.my.cnfAffichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Un nom court pour la boutique
alias sql='mariadb -h db -u student -pstudent shop -t -e'Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
La commande 38 ne montre qu'un numéro
sql "SELECT id, customer_id, status FROM orders WHERE id = 38"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
JOIN ... ON recolle les lignes qui vont ensemble
Pour voir le client de la commande 38, la requête nomme les deux tables. JOIN les relie. ON donne la condition : le customer_id de la commande est égal au id du client.
On donne un alias à chaque table, o et c, pour écrire moins. Chaque colonne s'écrit alors c.last_name, pour dire de quelle table elle vient.
Exemple : comment la base recolle les lignes
| Ligne de orders | customer_id | Ligne de customers trouvée | Résultat |
|---|---|---|---|
| 38 | 14 | id 14, Jack Dubois, Tokyo | une ligne avec la commande et le client |
| 43 | 30 | id 30, Omar Moreau, Cardiff | une ligne avec la commande et le client |
| 7 | 99 | aucune ligne n'a l'id 99 | aucune ligne dans le résultat (impossible ici, la clé le refuse) |
Les cellules que les étudiants remplissent restent vides dans cet aperçu.
Les commandes en attente et leur client
sql "SELECT o.id, c.last_name, c.city FROM orders o JOIN customers c ON c.id = o.customer_id WHERE o.status = 'pending' ORDER BY o.id"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Ce que contient la commande 70
sql "SELECT i.order_id, p.name, i.quantity FROM order_items i JOIN products p ON p.id = i.product_id WHERE i.order_id = 70 ORDER BY p.name"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
LEFT JOIN garde aussi les lignes sans correspondance
Un JOIN simple oublie les lignes qui n'ont aucune correspondance. Un client qui n'a jamais commandé disparaît du résultat.
LEFT JOIN garde toutes les lignes de la table de gauche. Quand rien ne correspond, les colonnes de droite valent NULL. On peut alors chercher IS NULL pour trouver les lignes seules.
Les clients qui n'ont jamais commandé
sql "SELECT c.id, c.first_name, c.last_name FROM customers c LEFT JOIN orders o ON o.customer_id = c.id WHERE o.id IS NULL ORDER BY c.id"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Articles de 25 à 30 euros, avec JOIN
sql "SELECT p.name, c.name AS rayon FROM products p JOIN categories c ON c.id = p.category_id WHERE p.price BETWEEN 25 AND 30 ORDER BY p.name"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Les mêmes articles, avec LEFT JOIN
sql "SELECT p.name, c.name AS rayon FROM products p LEFT JOIN categories c ON c.id = p.category_id WHERE p.price BETWEEN 25 AND 30 ORDER BY p.name"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une jointure sans condition
sql "SELECT COUNT(*) AS lignes FROM customers CROSS JOIN orders"Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.
Une erreur fréquente
Attention
Beaucoup pensent qu'oublier la condition ON ne change presque rien. La base associe alors chaque client à chaque commande : 40 clients fois 120 commandes font 4 800 lignes, au lieu de 120. Écris toujours ON, et vérifie que le nombre de lignes a du sens.
À toi : les membres et leur club
-- Le prénom de chaque membre à côté du nom de son club.
SELECT m.prenom, c.nom AS club
FROM membres m
JOIN clubs c ON c.id = m.club_id
ORDER BY m.prenom;
-- Remplace JOIN par LEFT JOIN : qui apparaît en plus, et avec quoi ?