Comment interroger plusieurs tables de base de données à la fois avec des jointures SQL

L'un des plus grands avantages de l'utilisation de bases de données relationnelles telles que MySQL est que sa structure relationnelle vous permet de stocker et d'interroger facilement des informations sur plusieurs tables.

Explorons comment récupérer exactement les données souhaitées à partir de plusieurs tables de base de données et les différentes jointures disponibles qui vous permettent d'extraire les résultats exacts que vous souhaitez.

Initialiser l'exemple de base de données

Ce n'est pas obligatoire, mais si vous souhaitez suivre les exemples de cet article, vous pouvez initialiser un exemple de base de données localement avec les commandes de terminal ci-dessous:

 git clone https://github.com/mdizak/sample-select-db.git
cd sample-select-db
sudo mysql < store.sql
sudo mysql sampledb
mysql> SELECT COUNT(*) FROM customers;

Vous devriez obtenir un résultat indiquant qu'il y a 2000 lignes dans la table des clients .

Jointure par défaut / INNER

La jointure par défaut utilisée dans les bases de données MySQL s'appelle la jointure INNER et est la plus courante et la plus simple. Cette jointure renvoie tous les enregistrements pour lesquels il existe des enregistrements correspondants dans les deux tables et rejette tous les autres enregistrements.

Par exemple, si vous souhaitez voir le prénom et le nom du client, ainsi que le montant et la date de la commande pour toutes les commandes supérieures à 1 000 USD, vous pouvez utiliser l'instruction SQL suivante:

 
SELECT
c.id, c.first_name, c.last_name, o.amount, o.created_at
FROM
customers c, orders o
WHERE
o.customer_id = c.id AND o.amount >= 1000;

Quelques notes concernant la requête ci-dessus:

  • Cinq colonnes différentes sont sélectionnées, trois de la table des clients et deux de la table des commandes.
  • Dans la clause FROM, les deux tables sont définies, mais avec le suffixe des lettres «c» et «o». Ceux-ci spécifient simplement des alias dans SQL, peuvent être tout ce que vous souhaitez et sont utilisés pour raccourcir la requête SQL.
  • O.customer_id = c.id est l'aspect de jointure de la requête et garantit une corrélation appropriée entre les clients et les commandes.

Une manière différente, et techniquement plus correcte du point de vue syntaxique, d'écrire la même requête est ci-dessous:

 
SELECT
c.id, c.first_name, c.last_name, o.amount, o.created_at
FROM
customers c INNER JOIN orders o
ON
customer_id = c.id
WHERE
o.amount >= 1000;

La requête ci-dessus a tendance à être un peu plus facile à lire car vous pouvez facilement voir la jointure entre la table des clients et des commandes. À toutes fins utiles, ces deux requêtes sont identiques et produiront exactement les mêmes enregistrements.

Jointures GAUCHE

Les jointures à gauche renverront tous les enregistrements de la table de gauche qui correspondent également aux enregistrements de la table de droite et ignoreront tous les autres enregistrements. Par exemple, vous souhaitez peut-être afficher le montant total des ventes pour chaque produit de la base de données, vous pouvez essayer d'utiliser une requête telle que:

 
SELECT
p.name, sum(item.amount) AS tamount
FROM
orders_items item LEFT JOIN products p
ON
item.product_id = p.id
GROUP BY item.product_id ORDER BY tamount DESC

Cela se traduit par une belle vue à deux colonnes montrant le nom du produit avec le montant total des ventes et fonctionne comme prévu. La requête a parcouru tous les produits de la table orders_items, les a joints aux enregistrements de la table products et a renvoyé le montant total des ventes de chacun.

Jointures DROITE

En utilisant l'exemple ci-dessus, notez que la requête ci-dessus n'a renvoyé que 19 enregistrements alors qu'il y a un total de 22 produits dans la base de données. Cela est dû au fait que la requête a commencé avec la table orders_items et l'a jointe à la table products, et comme certains produits n'ont jamais été commandés, aucun enregistrement de ces produits n'existe dans la table orders_items.

Que se passe-t-il si vous souhaitez obtenir une liste de tous les produits avec des montants de vente, y compris les produits qui n'ont pas été commandés? Essayez une jointure droite avec la requête suivante:

 
SELECT
p.name, sum(item.amount) AS tamount
FROM
orders_items item RIGHT JOIN products p
ON
item.product_id = p.id
GROUP BY p.id ORDER BY tamount DESC

C'est mieux, et la requête renvoie maintenant les 22 produits complets, trois d'entre eux ayant un montant nul . En effet, au lieu d'utiliser orders_items comme table principale qui se joint à la table products, la jointure droite inverse la commande et joint la table products à la table orders_items.

Jointures multiples dans une requête

Parfois, vous devez joindre trois ou plusieurs tables ensemble pour obtenir un ensemble spécifique de résultats.

Par exemple, vous souhaitez peut-être une liste de tous les clients qui ont acheté le micro-ondes (numéro de produit n ° 1), y compris leur nom et la date de la commande. Cela nécessite un SELECT sur trois tables, ce qui peut être effectué en utilisant deux jointures avec la requête suivante:

 
SELECT
c.first_name, c.last_name, o.amount, o.created_at
FROM
customers c INNER JOIN orders o
ON
c.id = o.customer_id INNER JOIN orders_items item
ON
item.order_id = o.id
WHERE
item.product_id = 1 ORDER BY o.created_at;

Cette requête renvoie toutes les 426 commandes du micro-ondes et fonctionne comme prévu. Il associe d'abord tous les clients à leurs commandes respectives, puis d'autres requêtes qui résultent en faisant correspondre toutes les commandes à celles de la table orders_items qui contiennent le produit micro-ondes (id # 1).

Ne jamais utiliser de sous-requêtes avec des clauses IN

En bref, à tout prix, vous devez toujours éviter d'utiliser des sous-requêtes dans vos requêtes SQL telles que:

 SELECT first_name,last_name FROM customers WHERE id IN (SELECT customer_id FROM orders WHERE status = 'approved' AND amount < 100);

Les requêtes telles que ci-dessus sont très inefficaces, utilisent un grand nombre de ressources et doivent être évitées autant que possible. Utilisez plutôt des jointures appropriées comme indiqué dans les sections ci-dessus. Par exemple, la requête ci-dessus doit être réécrite comme suit:

 SELECT c.first_name, c.last_name FROM customers c LEFT JOIN orders o ON o.customer_id = c.id WHERE o.status = 'approved' AND o.amount < 100;

Gagnez du temps avec les jointures SQL

Nous espérons que cet article vous aidera à montrer la puissance des bases de données relationnelles telles que MySQL et comment créer des requêtes SQL qui récupèrent des enregistrements de plusieurs tables dans une seule requête à l'aide de jointures, vous permettant de récupérer les résultats exacts souhaités.

Vous avez appris trois jointures différentes dans SQL, comment créer des alias pour les noms de colonnes et de tables, utiliser plusieurs jointures dans une requête et pourquoi vous devez éviter les sous-requêtes. Ne vous brouillez plus jamais en essayant de compiler manuellement différents ensembles de données en un seul et commencez à utiliser des jointures pour impressionner vos collègues de travail et gagner du temps.